我按照本教程https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#0的操作,使用Room和Couroutines创建了一个Sqlite数据库。一切正常,但是我无法(而且我也不明白为什么)在我的应用程序中创建默认数据。在我的代码下面
@Database(entities = [Challenge::class, ChallengeDay::class], version = 1)
abstract class MyDB: RoomDatabase() {
abstract fun challengeDao(): ChallengeDao
abstract fun challengeDayDao(): ChallengeDayDao
companion object {
@Volatile
private var INSTANCE: MyDB? = null
fun getDatabase(ctx: Context, scope: CoroutineScope): MyDB {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(ctx.applicationContext, MyDB::class.java, "MY_DATABASE").addCallback(MyDBCallback(scope)).build()
INSTANCE = instance
instance
}
}
private class MyDBCallback(private val scope: CoroutineScope): RoomDatabase.Callback() {
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
INSTANCE?.let { database ->
scope.launch(Dispatchers.IO) {
populateDatabase(database.challengeDao(), database.challengeDayDao())
}
}
}
}
suspend fun populateDatabase(challengeDao: ChallengeDao, challengeDayDao: ChallengeDayDao) {
val standardChallenge = Challenge(name = "Standard challenge", standard = true)
val id = challengeDao.insert(standardChallenge)
challengeDayDao.insert(ChallengeDay(numberOfDay = 1, done = false, challengeId = id, seconds = 20))
challengeDayDao.insert(ChallengeDay(numberOfDay = 2, done = false, challengeId = id, seconds = 20))
challengeDayDao.insert(ChallengeDay(numberOfDay = 3, done = false, challengeId = id, seconds = 30))
challengeDayDao.insert(ChallengeDay(numberOfDay = 4, done = false, challengeId = id, seconds = 30))
challengeDayDao.insert(ChallengeDay(numberOfDay = 5, done = false, challengeId = id, seconds = 20))
challengeDayDao.insert(ChallengeDay(numberOfDay = 6, done = false, challengeId = id, seconds = null))
challengeDayDao.insert(ChallengeDay(numberOfDay = 7, done = false, challengeId = id, seconds = 45))
challengeDayDao.insert(ChallengeDay(numberOfDay = 8, done = false, challengeId = id, seconds = 45))
challengeDayDao.insert(ChallengeDay(numberOfDay = 9, done = false, challengeId = id, seconds = 60))
challengeDayDao.insert(ChallengeDay(numberOfDay = 10, done = false, challengeId = id, seconds = 60))
}
}
}
我像这样从getDatabase
类调用函数ViewModel
class ChallengeViewModel(application: Application): AndroidViewModel(application) {
private val challengeRepository: ChallengeRepository
val challenges: LiveData<List<Challenge>>
init {
val challengeDao = MyDB.getDatabase(application, viewModelScope).challengeDao()
challengeRepository = ChallengeRepository(challengeDao)
challenges = challengeRepository.allChallenges
}
}
我注意到我第一次运行该应用程序时,将创建数据库,但是它是空的。如果我停止应用程序,然后重新运行,数据库将填充默认数据。
另一个疑问。当我在数据库中写入默认数据时,如何避免在每次运行该应用程序时调用populateDatabase
?
感谢所有人。