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, которая будет уметь добавлять новые слова в БД.