apply plugin: 'kotlin-kapt' android { packagingOptions { exclude'META-INF/atomicfu.kotlin_module' } } dependencies { // Dependencies for working with Architecture components // You'll probably have to update the version numbers in guild.gradle (Project) implementation "androidx.room:room-runtime:$rootProject.roomVersion" implementation "androidx.room:room-ktx:$rootProject.roomVersion" kapt "androidx.room:room-compiler:$rootProject.roomVersion"
@Dao interfaceWordDao{ @Query("SELECT * from word_table ORDER BY word ASC") fungetAllWords(): LiveData<List<Word>> @Insert(onConflict = OnConflictStrategy.REPLACE) suspendfuninsert(word: Word) @Query("DELETE FROM word_table") suspendfundeleteAll() }
fungetDatabase( 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" ) //如果数据库升级,无法迁移时,删除重建 .fallbackToDestructiveMigration() .addCallback(WordDatabaseCallback(scope)) .build() INSTANCE = instance // return instance instance } }
privateclassWordDatabaseCallback( privateval scope: CoroutineScope ) : RoomDatabase.Callback() { /** * Override the onOpen method to populate the database. * For this sample, we clear the database every time it is created or opened. */ overridefunonOpen(db: SupportSQLiteDatabase) { super.onOpen(db) // If you want to keep the data through app restarts, // comment out the following line. INSTANCE?.let { database -> scope.launch { populateDatabase(database.wordDao()) } } } }
var word = Word("Hello") wordDao.insert(word) word = Word("World!") wordDao.insert(word) } }
}
Repository:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Declares the DAO as a private property in the constructor. Pass in the DAO // instead of the whole database, because you only need access to the DAO classWordRepository(privateval wordDao: WordDao) {
// Room executes all queries on a separate thread. // Observed LiveData will notify the observer when the data has changed. val allWords: LiveData<List<Word>> = wordDao.getAllWords()
// The suspend modifier tells the compiler that this must be called from a // coroutine or another suspend function. suspendfuninsert(word: Word) { wordDao.insert(word) } }
// Class extends AndroidViewModel and requires application as a parameter. classWordViewModel(application: Application) : AndroidViewModel(application) {
// The ViewModel maintains a reference to the repository to get data. privateval repository: WordRepository // LiveData gives us updated words when they change. val allWords: LiveData<List<Word>>
init { // Gets reference to WordDao from WordRoomDatabase to construct // the correct WordRepository. val wordsDao = getDatabase(application, viewModelScope).wordDao() repository = WordRepository(wordsDao) allWords = repository.allWords }
// The implementation of insert() is completely hidden from the UI. // We don't want insert to block the main thread, so we're launching a new // coroutine. ViewModels have a coroutine scope based on their lifecycle called // viewModelScope which we can use here. funinsert(word: Word) = viewModelScope.launch { repository.insert(word) } }
调用:
1 2 3 4 5 6 7 8
privatelateinitvar wordViewModel: WordViewModel wordViewModel = ViewModelProviders.of(this).get(WordViewModel::class.java) wordViewModel.allWords.observe(this, Observer { words -> // Update the cached copy of the words in the adapter. words?.let { adapter.setWords(it) } }) //插入 wordViewModel.insert(word)