【发布时间】:2023-03-11 07:33:01
【问题描述】:
我有一个应用程序,我在其中使用 json 文件预填充我的房间数据库。这是我的数据库设置:
@Database(version = 2, entities = [(ClimbingRoute::class)], exportSchema = false)
abstract class ClimbingRoutesDatabase : RoomDatabase() {
abstract fun climbingRouteDao(): ClimbingRouteDao
private class ClimbingRouteDatabaseCallback(
private val scope: CoroutineScope,
private val resources: Resources
) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
INSTANCE?.let { database ->
//1
scope.launch{
val climbingRouteDao = database.climbingRouteDao() // 2
prePopulateDatabase(climbingRouteDao) // 3
} }
}
private suspend fun prePopulateDatabase(climbingRouteDao: ClimbingRouteDao){
// 1
val jsonString = resources.openRawResource(R.raw.climbing_routes).bufferedReader().use {
it.readText()
}
// 2
val typeToken = object : TypeToken<List<ClimbingRoute>>() {}.type
val boulderClimbingRoutes = Gson().fromJson<List<ClimbingRoute>>(jsonString, typeToken)
// 3
climbingRouteDao.insertAllClimbingRoutes(boulderClimbingRoutes)
}
}
companion object {
@Volatile
private var INSTANCE: ClimbingRoutesDatabase? = null
fun getDatabase(
context: Context,
coroutineScope: CoroutineScope, // 1
resources: Resources // 2
): ClimbingRoutesDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(context.applicationContext,
ClimbingRoutesDatabase::class.java,
"climbing_routes_database")
.addCallback(ClimbingRouteDatabaseCallback(coroutineScope, resources))
.build()
INSTANCE = instance
return instance
}
}
}
}
现在我正在学习使用 Hilt 的 codingwithflow 教程。我想使用他的模式将依赖注入添加到我的应用程序中。这是他的教程中codingwithflow的TaskDatabase和AppModule。
他的任务数据库
@Database(entities = [Task::class], version = 1)
abstract class TaskDatabase : RoomDatabase() {
abstract fun taskDao(): TaskDao
class Callback @Inject constructor(
private val database: Provider<TaskDatabase>,
@ApplicationScope private val applicationScope: CoroutineScope,
) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
val dao = database.get().taskDao()
applicationScope.launch {
dao.insert(Task("Wash the dishes"))
dao.insert(Task("Do the laundry"))
dao.insert(Task("Buy groceries", important = true))
dao.insert(Task("Prepare food", completed = true))
dao.insert(Task("Call mom"))
dao.insert(Task("Visit grandma", completed = true))
dao.insert(Task("Repair my bike"))
dao.insert(Task("Call Elon Musk"))
}
}
}
}
他的 AppModule:
@Module
@InstallIn(ApplicationComponent::class)
object AppModule {
@Provides
@Singleton
fun provideDatabase(
app: Application,
callback: TaskDatabase.Callback
) = Room.databaseBuilder(app, TaskDatabase::class.java, "task_database")
.fallbackToDestructiveMigration()
.addCallback(callback)
.build()
@Provides
fun provideTaskDao(db: TaskDatabase) = db.taskDao()
@ApplicationScope
@Provides
@Singleton
fun provideApplicationScope() = CoroutineScope(SupervisorJob())
}
@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class ApplicationScope
我已尝试将这种方法用于我的应用程序,但无法使用我的带有依赖注入的 json 成功预填充数据库。应用程序正在加载,没有崩溃,但我一直得到一个空数据库。
我对 di 的理解还不够,无法修改 appmodule 以使其工作。这是我现在的数据库设置、appmodule 和 dao。 (不工作):
我的攀登路线数据库:
@Database(entities = [(ClimbingRoute::class)], version = 1, exportSchema = false)
abstract class ClimbingRouteDatabase : RoomDatabase() {
abstract fun climbingRouteDao(): ClimbingRouteDao
class Callback @Inject constructor(
private val database: Provider<ClimbingRouteDatabase>,
@ApplicationScope private val applicationScope: CoroutineScope,
private val resources: Resources
) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
val climbingRouteDao = database.get().climbingRouteDao()
applicationScope.launch{
prePopulateDatabase(climbingRouteDao)
}
}
private suspend fun prePopulateDatabase(climbingRouteDao: ClimbingRouteDao){
val jsonString = resources.openRawResource(R.raw.climbing_routes).bufferedReader().use {
it.readText()
}
val typeToken = object : TypeToken<List<ClimbingRoute>>() {}.type
val boulderClimbingRoutes = Gson().fromJson<List<ClimbingRoute>>(jsonString, typeToken)
climbingRouteDao.insert(boulderClimbingRoutes)
}
}
}
我的应用模块:
@Module
@InstallIn(ApplicationComponent::class)
object AppModule {
@Provides
@Singleton
fun provideDatabase(
app: Application,
callback: ClimbingRouteDatabase.Callback
) = Room.databaseBuilder(
app,
ClimbingRouteDatabase::class.java,
"climbing_route_database")
.fallbackToDestructiveMigration()
.addCallback(callback)
.build()
@Provides
fun provideClimbingRouteDao(db: ClimbingRouteDatabase) = db.climbingRouteDao()
@Provides
@Singleton
fun resourcesProvider(@ApplicationContext context: Context): Resources = context.resources
@ApplicationScope
@Provides
@Singleton
fun provideApplicationScope() = CoroutineScope(SupervisorJob())
}
@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class ApplicationScope
攀登路线道
@Dao
interface ClimbingRouteDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(climbingRoutes: List<ClimbingRoute>)
@Query("SELECT * FROM climbing_route_table")
fun getClimbingRoutes(): Flow<List<ClimbingRoute>>
@Update
suspend fun update(climbingRoutes: ClimbingRoute)
@Delete
suspend fun delete(climbingRoutes: ClimbingRoute)
}
任何帮助将不胜感激。谢谢。
【问题讨论】:
标签: android dependency-injection android-room dagger-hilt android-database