首页 > 解决方案 > 如何将一些默认数据加载到数据库中

问题描述

我按照本教程https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#0使用 Room 和 couroutines 创建了一个 Sqlite DB。一切正常,但我无法(而且我不明白为什么)在我的应用程序中创建默认数据。在我的代码下面

@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每次运行应用程序时调用?

谢谢大家。

标签: androidsqlitekotlinandroid-room

解决方案


推荐阅读