Android 使用WorkManager和Dagger预填充房间数据库

Android 使用WorkManager和Dagger预填充房间数据库,android,android-room,dagger,android-workmanager,Android,Android Room,Dagger,Android Workmanager,我尝试在创建数据库时使用WorkManager填充房间数据库。我正在使用dagger初始化数据库及其Dao。 对数据库进行种子设定时,会出现以下错误 Could not instantiate *.*.*.SeedDatabaseWorker java.lang.NoSuchMethodException: <init> [class android.content.Context, class androidx.work.WorkerParameters]

我尝试在创建数据库时使用WorkManager填充房间数据库。我正在使用dagger初始化数据库及其Dao。 对数据库进行种子设定时,会出现以下错误

Could not instantiate *.*.*.SeedDatabaseWorker
    java.lang.NoSuchMethodException: <init> [class android.content.Context, class androidx.work.WorkerParameters]
        at java.lang.Class.getConstructor0(Class.java:2204)
        at java.lang.Class.getDeclaredConstructor(Class.java:2050)
        at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:91)
        at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:233)
        at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:127)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
2019-03-16 16:22:29.135 18035-18051/*.* E/WM-WorkerWrapper: Could not create Worker *.*.*.SeedDatabaseWorker
SeedDatabaseWorker.kt

@Provides
@Singleton
fun provideAppDatabase(context: Context): AppDatabase {
    return Room.databaseBuilder(
        context,
        AppDatabase::class.java,
        "garden.db"
    )
        .addCallback(object : RoomDatabase.Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                super.onCreate(db)
                val request = OneTimeWorkRequestBuilder<SeedDatabaseWorker>().build()
                WorkManager.getInstance().enqueue(request)
            }
        })
        .build()
}

@Provides
@Singleton
fun providePlantDao(db: AppDatabase): PlantDao =
    db.plantDao()
@Database(
        entities = [
            Plant::class
        ],
        version = 1,
        exportSchema = false
)
abstract class AppDatabase : RoomDatabase() {

    abstract fun plantDao(): PlantDao
}
class SeedDatabaseWorker @Inject constructor(
        context: Context,
        workerParameters: WorkerParameters
): CoroutineWorker(context, workerParameters) {


    private val TAG by lazy { SeedDatabaseWorker::class.java.simpleName }
    @Inject
    lateinit var database: AppDatabase
    override val coroutineContext = Dispatchers.IO

    override suspend fun doWork(): Result = coroutineScope {

        try {
            applicationContext.assets.open("plants.json").use { inputStream ->
                JsonReader(inputStream.reader()).use { jsonReader ->
                    val plantType = object : TypeToken<List<Plant>>() {}.type
                    val plantList: List<Plant> = Gson().fromJson(jsonReader, plantType)

                    database.plantDao().insertAll(plantList)

                    Result.success()
                }
            }
        } catch (ex: Exception) {
            Log.e(TAG, "Error seeding database", ex)
            Result.failure()
        }
    }
}
class SeedDatabaseWorker@Inject构造函数(
上下文:上下文,
workerParameters:workerParameters
):CoroutineWorker(上下文、workerParameters){
惰性{SeedDatabaseWorker::class.java.simpleName}的私有val标记
@注入
lateinit变量数据库:AppDatabase
override val coroutineContext=Dispatchers.IO
重写suspend fun doWork():Result=coroutineScope{
试一试{
applicationContext.assets.open(“plants.json”)。使用{inputStream->
JsonReader(inputStream.reader())。使用{JsonReader->
val plantType=object:TypeToken(){}.type
val plantList:List=Gson().fromJson(jsonReader,plantType)
database.plantDao().insertAll(plantList)
结果:成功()
}
}
}捕获(例如:异常){
Log.e(标签,“错误种子数据库”,ex)
结果.失败()
}
}
}
有人能帮我用WorkManager填充数据库吗?
注意:我现在正在尝试这个

,Dagger 2不正式支持使用
androidx.worker.worker
进行注射,此问题仍然存在,请检查。本文提出了一种解决方案。基本上,您可以在构造函数中注入任何对象,如:

class HelloWorldWorker@AssistedInject构造函数(
@辅助私有val appContext:Context,
@辅助私有val参数:WorkerParameters,
二等兵法尔福:福
):Worker(appContext,params){
private val TAG=“HelloWorldWorker”
重写fun doWork():结果{
Log.d(标记“Hello world!”)
Log.d(标签,“注入的foo:$foo”)
返回Result.success()
}
@辅助工程厂
接口工厂:ChildWorkerFactory
}
这里注入对象
Foo

在我的项目中,我也遇到了同样的问题,受这个问题的启发,我解决了这个问题。
您可以检查以了解如何使用WorkManager预填充数据。

目前,Dagger 2不正式支持使用androidx.worker.worker进行注入。,此问题仍然存在,请检查。本文提出了一种解决方案。基本上,您可以在构造函数中注入任何对象,如:

class HelloWorldWorker@AssistedInject构造函数(
@辅助私有val appContext:Context,
@辅助私有val参数:WorkerParameters,
二等兵法尔福:福
):Worker(appContext,params){
private val TAG=“HelloWorldWorker”
重写fun doWork():结果{
Log.d(标记“Hello world!”)
Log.d(标签,“注入的foo:$foo”)
返回Result.success()
}
@辅助工程厂
接口工厂:ChildWorkerFactory
}
这里注入对象
Foo

在我的项目中,我也遇到了同样的问题,受这个问题的启发,我解决了这个问题。
您可以检查以查看如何使用WorkManager预填充数据。

不要注入您的工作者构造函数,请从
种子数据库工作者
构造函数中移除
@inject
。如果移除[@inject]@JeelDon不注入您的工作者构造函数,我将如何获取数据库引用,从
SeedDatabaseWorker
构造函数中删除
@Inject
。如果删除[@Inject]@Jeel“我的解决方案”:死链接“我的解决方案”:死链接,我将如何获取数据库的引用
class SeedDatabaseWorker @Inject constructor(
        context: Context,
        workerParameters: WorkerParameters
): CoroutineWorker(context, workerParameters) {


    private val TAG by lazy { SeedDatabaseWorker::class.java.simpleName }
    @Inject
    lateinit var database: AppDatabase
    override val coroutineContext = Dispatchers.IO

    override suspend fun doWork(): Result = coroutineScope {

        try {
            applicationContext.assets.open("plants.json").use { inputStream ->
                JsonReader(inputStream.reader()).use { jsonReader ->
                    val plantType = object : TypeToken<List<Plant>>() {}.type
                    val plantList: List<Plant> = Gson().fromJson(jsonReader, plantType)

                    database.plantDao().insertAll(plantList)

                    Result.success()
                }
            }
        } catch (ex: Exception) {
            Log.e(TAG, "Error seeding database", ex)
            Result.failure()
        }
    }
}