Course Content
-
Сохраняем данные в Room + ViewModel
- Коротко об Android Architecture Components и Room
- Создание проекта и добавление необходимых зависимостей
- Создание Entity
- Создание DAO
- Знакомство с LiveData
- Создание базы данных Room
- Знакомство с патерном Repository (Репозиторий) и создание слоя для доступа к данным
- Создание ViewModel
- Создание ячейки списка для отображения UI
- Создание адаптера и добавление RecyclerView
- Добавление записи в БД используя Room
- Создание Activity
- Подключение к базе данных Room
- Итоги
Добавление записи в БД используя Room
В данный момент в нашей БД нет данных. Мы рассмотрим добавление данных двумя способами: добавим часть данных вручную, открыв соединение с базой данных, а второй – создадим Activity для добавления новых слов. Для удаления всех данных и заполнения базы данных записями, мы создадим RoomDatabase.Callback и переопределим метод onOpen(). Кроме того, так как по умолчанию Room не позволяет обращаться к базе данных в главном потоке, onOpen() использует корутины для фоновой работы.
Чтобы запустить работу в фоновом потоке нам необходим CoroutineScope Обновите метод getDatabase в классе WordRoomDatabase чтобы передать скоуп в качестве параметра:
fun getDatabase(
context: Context,
scope: CoroutineScope
): WordRoomDatabase {
...
}
Также не забудьте обновить блок init в WordViewModel для того, чтобы тоже передать скоуп:
val wordsDao = WordRoomDatabase.getDatabase(application, viewModelScope).wordDao()
Для наполнения БД записями, необходимо реализовать RoomDatabase.Callback() который также принимает CoroutineScope в качестве аргумента в конструкторе. После этого, необходимо переопределить метод onOpen для заполнения базы данных записями.
private class WordDatabaseCallback(
private val scope: CoroutineScope
) : RoomDatabase.Callback() {
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
INSTANCE?.let { database ->
scope.launch {
populateDatabase(database.wordDao())
}
}
}
suspend fun populateDatabase(wordDao: WordDao) {
// Delete all content here.
wordDao.deleteAll()
// Add sample words.
var word = Word("Hello")
wordDao.insert(word)
word = Word("World!")
wordDao.insert(word)
// TODO: Add your own words!
}
}
После этого, добавьте реализованный колбэк в метод создания экземпляра базы данных
.addCallback(WordDatabaseCallback(scope))
В итоге мы должны получить такой код:
@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {
abstract fun wordDao(): WordDao
private class WordDatabaseCallback(
private val scope: CoroutineScope
) : RoomDatabase.Callback() {
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
INSTANCE?.let { database ->
scope.launch {
var wordDao = database.wordDao()
// Delete all content here.
wordDao.deleteAll()
// Add sample words.
var word = Word("Hello")
wordDao.insert(word)
word = Word("World!")
wordDao.insert(word)
// TODO: Add your own words!
word = Word("TODO!")
wordDao.insert(word)
}
}
}
}
companion object {
@Volatile
private var INSTANCE: WordRoomDatabase? = null
fun getDatabase(
context: Context,
scope: CoroutineScope
): WordRoomDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
WordRoomDatabase::class.java,
"word_database"
)
.addCallback(WordDatabaseCallback(scope))
.build()
INSTANCE = instance
// return instance
instance
}
}
}
Осталось совсем немного! В следующем уроке мы создадим activity, которая будет уметь добавлять новые слова в БД.