首页 > 解决方案 > 如何注入 Worker 类?

问题描述

因此,首先我创建了名为 UpdaterWorker 的工人类。之后,我在我的应用程序类中覆盖了 getWorkManagerConfiguration。我创建了一个 WorkerFactory 类。

这就是我所要做的,还是我错过了什么?

如何创建一次性请求?

当我尝试将 updater worker 注入主要活动时,我收到此错误:Dagger 不支持注入 @AssistedInject 类型,.workmanager.UpdaterWorker。你的意思是注入它的辅助工厂类型吗?

**Updater worker**

@HiltWorker
class UpdaterWorker @AssistedInject constructor(
    private val api: ReservationApi,
    private val updaterUrl: String,
    private val prefManager: PrefManager,
    @Assisted private val context: Context,
    @Assisted workerParams: WorkerParameters
) : Worker(context, workerParams) {
...
}

** Worker Factory**
class WorkerFactory @Inject constructor(
    private val api: ReservationApi,
    @param:Named("update_url") private val updaterUrl: String,
    private val prefManager: PrefManager,
) : WorkerFactory() {

    override fun createWorker(
        appContext: Context,
        workerClassName: String,
        workerParameters: WorkerParameters
    ): ListenableWorker? {
        return when (workerClassName) {
            WorkerEnums.UpdaterWorker.name -> {
                UpdaterWorker(api, updaterUrl, prefManager, appContext, workerParameters)
            }
            else ->
                throw Resources.NotFoundException("Worker not found")
        }
    }
}
** My application class**
    override fun getWorkManagerConfiguration(): Configuration {
        return Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
    }

**Main Activity**
    @Inject
    lateinit var updaterWorker: UpdaterWorker

标签: androidkotlindagger-hilt

解决方案


不需要 WorkerFactory,此外,您不需要(也不能)将 Worker 注入任何其他类。这是正确的方法:

工人

@HiltWorker
class UpdaterWorker @AssistedInject constructor(
    private val api: ReservationApi,
    private val updaterUrl: String,
    private val prefManager: PrefManager,
    @Assisted private val context: Context,
    @Assisted workerParams: WorkerParameters
) : Worker(context, workerParams) {
...
}

Worker 的使用(例如在 viewmodel 中)

class MyTestViewModelForWorker(@ApplicationContext private val context: Context) : ViewModel() {
     private val myTestWork = OneTimeWorkRequestBuilder<UpdateWorker>
        .build()

    fun startManager() {
        WorkManager.getInstance(context).enqueue(myTestWork)
    }

}

然后,使用应用程序类中的 hiltfactory 覆盖默认 workerfactory 很重要

覆盖默认的 WorkerFactory

@HiltAndroidApp
class App : Application(), Configuration.Provider {
    @Inject lateinit var workerFactory: HiltWorkerFactory

    override fun getWorkManagerConfiguration(): Configuration =
        Configuration.Builder().setWorkerFactory(workerFactory).build()
}

最后,您需要删除清单中的默认 workmanagerinitalizator:

应用清单

<provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    tools:node="remove" />

下次,请阅读 hilt 的文档,因为我在这里写的所有内容都在那里得到了完美的解释,其次,我在这里展示的方法将随着版本的发布而改变androidx.work:work-runtime-ktx:2.6.0


推荐阅读