【问题标题】:Android. Could not instantiate Worker安卓。无法实例化 Worker
【发布时间】:2018-09-21 10:28:45
【问题描述】:

我想从 assets 文件夹中的 json 文件预填充我的 Room 数据库。我关注Google Sunflower sample。我复制了 SeedDatabaseWorker 类:

import android.content.Context
import android.util.Log
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.dmitrysimakov.gymlab.data.GymLabDb
import com.dmitrysimakov.gymlab.data.entity.Training
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import javax.inject.Inject

class SeedDatabaseWorker(val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    private val TAG = SeedDatabaseWorker::class.java.simpleName

    @Inject lateinit var database: GymLabDb

    override fun doWork(): Worker.Result {
        val plantType = object : TypeToken<List<Training>>() {}.type
        var jsonReader: JsonReader? = null

        return try {
            val inputStream = context.assets.open("training.json")
            jsonReader = JsonReader(inputStream.reader())
            val plantList: List<Training> = Gson().fromJson(jsonReader, plantType)
            database.trainingDao().insert(plantList)
            Worker.Result.SUCCESS
        } catch (ex: Exception) {
            Log.e(TAG, "Error seeding database", ex)
            Worker.Result.FAILURE
        } finally {
            jsonReader?.close()
        }
    }
}

我使用的是 Dagger 2,所以我不这样做:Sunflower AppDatabase,而是这样做:

import android.arch.persistence.db.SupportSQLiteDatabase
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.dmitrysimakov.gymlab.GymLabApp
import com.dmitrysimakov.gymlab.data.GymLabDb
import com.dmitrysimakov.gymlab.workers.SeedDatabaseWorker
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

@Module(includes = [ViewModelModule::class])
class AppModule {

    @Singleton
    @Provides
    fun provideDb(app: GymLabApp): GymLabDb {
        return Room
                .databaseBuilder(app, GymLabDb::class.java, "gymlab.db")
                .addCallback(object : RoomDatabase.Callback() {
                    override fun onCreate(db: SupportSQLiteDatabase) {
                        super.onCreate(db)
                        val request = OneTimeWorkRequestBuilder<SeedDatabaseWorker>().build()
                        WorkManager.getInstance().enqueue(request)
                    }
                })
                .fallbackToDestructiveMigration()
                .build()
    }

    @Singleton
    @Provides
    fun provideTrainingDao(db: GymLabDb) = db.trainingDao()
}

但是我无法注入尚未创建的数据库。那么,如何访问 dao?

【问题讨论】:

    标签: android dagger-2 android-room android-architecture-components android-workmanager


    【解决方案1】:

    问题是我无法将我的数据库注入到 Worker 中。我在这里找到了解决方案:AndroidWorkerInjection

    【讨论】:

      【解决方案2】:

      您的问题是 SeedDatabaseWorker 仍然基于现在已弃用的 Worker(),因此您需要使用 Worker(Context, WorkerParameters) 这个构造函数。

      查看我在another post 的回答,它将帮助您了解WorkManager 库。

      编辑:

      您现在可以在 Sunflower 演示中查看 Worker,它已更新。

      【讨论】:

      • @DmitrySimakov , 看一遍向日葵的例子,我相信你会明白的。
      • 但是无论如何我不能注入数据库,所以我无法获得dao。
      • 我来到这里是因为 alpha09 的问题。您正确地提到了 Worker() 已弃用。但是我可以确认这个构造函数仍在使用,而不是较新的Worker(Context, WorkerParameters)。现在,我将 both 构造函数添加到我的 worker 实现中。我也犯了一个错误,使工人 package protected。 worker 实现需要是 public。 (我使用的是 Java 版本。)
      • 是的,Worker() 计划在未来的版本中被删除,这就是为什么建议您使用Worker(Context, WorkerParameters)
      猜你喜欢
      • 2019-03-10
      • 2016-05-25
      • 2022-01-03
      • 1970-01-01
      • 2016-06-09
      • 2020-10-26
      • 2016-11-22
      • 2016-02-29
      • 2017-01-29
      相关资源
      最近更新 更多