在WorkManager的Worker中注入Repository

4

应用场景: 我需要从用户那里收集反馈,将其保存在持久存储中,这里使用的是 Room。并且每隔 X 分钟,我想将这些存储的 FeedbackRequest 发送到后端。

解决方案: 我考虑使用 WorkManager,因为此操作应该在进程死亡时保持执行,并且定期触发。我需要从 Room DB 获取 FeedbackRequest 列表,并使用 Retrofit 客户端将每个 FeedbackRequest 发送到后端。

问题定义: FeedbackRequestRepository 负责获取 FeedbackRequest 列表,需要在 WorkManager 的 doWork() 方法中使用它来从 Room DB 获取数据。此外,我对 Dagger2 还比较陌生。打开应用程序后,我遇到了上述错误。

AppComponent 代码片段

interface AppComponent {
@Component.Builder
interface Builder {
    @BindsInstance
    fun application(application: Application): Builder

    fun build(): AppComponent
}

fun inject(scFeedbackApp: ScFeedbackApp)
fun inject(dispatchWorker: DispatchWorker)

}

代码库片段

@Singleton
class FeedbackRequestRepository @Inject constructor(
        private val appExecutors: AppExecutors,
        private val db: ScFeedbackDB,
        private val feedbackAcknowledgeDao: FeedbackRequestDao,
        private val scFeedbackFeedbackService: SCFeedbackService
) {

...

}

工作代码片段

class DispatchWorker @Inject constructor(context:Context,
                             workerParameters: WorkerParameters,
                             var feedbackRequestRepository: FeedbackRequestRepository):
    Worker(context, workerParameters){
init {
    DaggerAppComponent.builder().application(context.applicationContext as ScFeedbackApp)
            .build().inject(this)
}
override fun doWork(): Result {

...

}

错误

E/WorkerFactory: Could not instantiate com.scfeedback.service.responseDispatcher.DispatchWorker
java.lang.NoSuchMethodException: <init> [class android.content.Context, class androidx.work.WorkerParameters]
    at java.lang.Class.getConstructor(Class.java:528)
    at java.lang.Class.getDeclaredConstructor(Class.java:507)
    at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:85)
    at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:188)
    at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:124)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
E/WorkerWrapper: Could not create Worker com.scfeedback.service.responseDispatcher.DispatchWorker
  1. 这与依赖注入设置有关吗?
  2. 如果不是,那我是哪里出错了呢?
1个回答

1

你的方法有两个问题:

  • 你不能同时应用构造函数注入 @inject constructor(...) 和直接注入 DaggerAppComponent...inject(this)
  • 你必须使用默认构造函数:

所以你可以将你的 DispatchWorker 更改为:

    class DispatchWorker constructor(context:Context,
                                 workerParameters: WorkerParameters):
        Worker(context, workerParameters){

        @Inject  lateinit var feedbackRequestRepository: FeedbackRequestRepository

    init {
        DaggerAppComponent.builder().application(context.applicationContext as ScFeedbackApp)
                .build().inject(this)
    }
    override fun doWork(): Result {

    ...

}

或者使用一个自定义的WorkerFactory

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接