使用 Hilt 预填充房间数据库
Prepopulating Room Database with Hilt
我正在尝试使用 RoomDatabase.Callback() 方法用数据预填充 Room 数据库,并且也成功地这样做了。后来我尝试对 Hilt 进行同样的操作,但无法弄清楚如何在 hilt 模块中提供数据库时添加回调。
这是数据库模块:
@Module
@InstallIn(ApplicationComponent::class)
object DatabaseModule {
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).build()
}
@Singleton
@Provides
fun provideDao(database: PersonDatabase) = database.personDao()
}
这是回调 class :
class PersonCallback @Inject constructor(
private val dao: PersonDao
) : RoomDatabase.Callback() {
private val applicationScope = CoroutineScope(SupervisorJob())
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
applicationScope.launch(Dispatchers.IO) {
populateDatabase()
}
}
private suspend fun populateDatabase() {
val person = Person("FirstName", "LastName", 20)
dao.insertData(person)
}
}
我尝试过使用数据库并提供像这样的 dao,但它卡在一个循环中,应用程序崩溃了。简而言之,错误是说,以下方式是递归的,因此是不允许的
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).addCallback(
PersonCallback(provideDatabase(context).personDao())
).build()
}
然后,我遵循了一个 SO post 并尝试复制它,即:
在上述之后,应用程序再次崩溃,提供了一个巨大的错误,该错误引用了自动生成的 class 并且没有任何意义可以使它更有意义
我尝试的另一种方法是将 dao 作为参数传递,但它再次崩溃并出现错误,说它导致依赖循环,因为我也将 dao 作为构造函数参数传递给存储库。
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context,
personDao: PersonDao
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).addCallback(
PersonCallback(personDao)
).build()
}
在所有这些尝试之后,我无法弄清楚我应该如何将 dao 传递给回调 class 并使其工作。我请求建议一些方法来实现这一点,或者任何替代方案也将不胜感激。
根据 link 你在你的问题中添加你找到解决方案只需编辑第一个方法提供 PersonDatabase
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context,
provider: Provider<PersonDao>
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).addCallback(
PersonCallback(provider)
).build()
}
然后你的回调 Class 为你的 class
编辑 PersonDao 的提供者
class PersonCallback (
private val provider: Provider<PersonDao>
) : RoomDatabase.Callback() {
private val applicationScope = CoroutineScope(SupervisorJob())
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
applicationScope.launch(Dispatchers.IO) {
populateDatabase()
}
}
private suspend fun populateDatabase() {
val person = Person("FirstName", "LastName", 20)
provider.get().insertData(person)
}
}
我试过这段代码对我来说工作得很好
我正在尝试使用 RoomDatabase.Callback() 方法用数据预填充 Room 数据库,并且也成功地这样做了。后来我尝试对 Hilt 进行同样的操作,但无法弄清楚如何在 hilt 模块中提供数据库时添加回调。
这是数据库模块:
@Module
@InstallIn(ApplicationComponent::class)
object DatabaseModule {
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).build()
}
@Singleton
@Provides
fun provideDao(database: PersonDatabase) = database.personDao()
}
这是回调 class :
class PersonCallback @Inject constructor(
private val dao: PersonDao
) : RoomDatabase.Callback() {
private val applicationScope = CoroutineScope(SupervisorJob())
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
applicationScope.launch(Dispatchers.IO) {
populateDatabase()
}
}
private suspend fun populateDatabase() {
val person = Person("FirstName", "LastName", 20)
dao.insertData(person)
}
}
我尝试过使用数据库并提供像这样的 dao,但它卡在一个循环中,应用程序崩溃了。简而言之,错误是说,以下方式是递归的,因此是不允许的
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).addCallback(
PersonCallback(provideDatabase(context).personDao())
).build()
}
然后,我遵循了一个 SO post 并尝试复制它,即:
在上述之后,应用程序再次崩溃,提供了一个巨大的错误,该错误引用了自动生成的 class 并且没有任何意义可以使它更有意义
我尝试的另一种方法是将 dao 作为参数传递,但它再次崩溃并出现错误,说它导致依赖循环,因为我也将 dao 作为构造函数参数传递给存储库。
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context,
personDao: PersonDao
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).addCallback(
PersonCallback(personDao)
).build()
}
在所有这些尝试之后,我无法弄清楚我应该如何将 dao 传递给回调 class 并使其工作。我请求建议一些方法来实现这一点,或者任何替代方案也将不胜感激。
根据 link 你在你的问题中添加你找到解决方案只需编辑第一个方法提供 PersonDatabase
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context,
provider: Provider<PersonDao>
): PersonDatabase {
return Room.databaseBuilder(
context,
PersonDatabase::class.java,
"person_database"
).addCallback(
PersonCallback(provider)
).build()
}
然后你的回调 Class 为你的 class
编辑 PersonDao 的提供者class PersonCallback (
private val provider: Provider<PersonDao>
) : RoomDatabase.Callback() {
private val applicationScope = CoroutineScope(SupervisorJob())
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
applicationScope.launch(Dispatchers.IO) {
populateDatabase()
}
}
private suspend fun populateDatabase() {
val person = Person("FirstName", "LastName", 20)
provider.get().insertData(person)
}
}
我试过这段代码对我来说工作得很好