gpt4 book ai didi

android - 使用 Hilt 预填充 Room 数据库,而无需创建额外的数据库实例

转载 作者:行者123 更新时间:2023-12-04 23:56:12 30 4
gpt4 key购买 nike

我试图确保我的数据库始终包含一个初始行。我通读了 How to populate Android Room database table on first run?我遇到的主要问题是,在创建数据库时,我无法使用 Hilt 访问(或者我不知道如何访问它?)。如果我尝试重新使用我编写的 provideDatabase Hilt 方法,它会导致 SQLite 数据库泄漏(可能是因为周围没有人使用这些生成的实例来关闭数据库)。这是我的代码:

@Module
@InstallIn(ApplicationComponent::class)
object AppModule {

@Singleton
@Provides
fun provideDatabase(@ApplicationContext context: Context): GameDatabase {
return Room.databaseBuilder(context, GameDatabase::class.java, GameDatabase.GAME_DB_NAME)
.addCallback(
object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
// Initialize the database with the first game
ioThread {
provideDatabase(context).gameDao().createNewGame(Game())
}
}

override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)

// Ensure there is always one game in the database
// This will capture the case of the app storage
// being cleared
// THIS results in an instance being created that can't be closed - causing DB leaks!
ioThread {
val gameDao = provideDatabase(context).gameDao()

if (gameDao.gameCount() == 0) {
gameDao.createNewGame(Game())
}
}
}
}
).build()
}

@Singleton
@Provides
fun provideGameDao(database: GameDatabase): GameDao {
return database.gameDao()
}
}

那么,我如何获得我的 DAO 来进行初始化呢?我是否只需要在 SQL 中手动制作插入语句并在数据库中调用它?

最佳答案

您的 provideDatabase 方法总是在每次调用时创建一个新实例:Dagger 通过仅调用该方法一次使其成为单例。获取由 ApplicationComponent 管理的单例 GameDatabase 实例的唯一方法是将其作为依赖项进行请求。由于 GameDatabase 需要通过 GameDao 依赖自身,这是一个循环依赖。

要解决 Dagger 中的循环依赖,您可以依赖 ProviderLazy :

    @Singleton
@Provides
fun provideDatabase(@ApplicationContext context: Context, gameDaoProvider: Provider<GameDao>): GameDatabase {
return Room.databaseBuilder(context, GameDatabase::class.java, GameDatabase.GAME_DB_NAME)
.addCallback(
object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
// Initialize the database with the first game
ioThread {
gameDaoProvider.get().createNewGame(Game())
}
}

override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)

// Ensure there is always one game in the database
// This will capture the case of the app storage
// being cleared
// This uses the existing instance, so the DB won't leak
ioThread {
val gameDao = gameDaoProvider.get()

if (gameDao.gameCount() == 0) {
gameDao.createNewGame(Game())
}
}
}
}
).build()
}

关于android - 使用 Hilt 预填充 Room 数据库,而无需创建额外的数据库实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65803302/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com