【问题标题】:Injecting Repository in WorkManager's Worker在 WorkManager 的 Worker 中注入存储库
【发布时间】:2018-10-25 10:24:56
【问题描述】:

用例:我需要从用户那里获取反馈,将其保存在持久存储中,在本例中为 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. 如果不是,那我哪里错了。

【问题讨论】:

    标签: android multithreading mvvm dependency-injection concurrency


    【解决方案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 {
    
        ...
    
    }
    

    或者使用custom WorkerFactory

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 2020-04-20
      相关资源
      最近更新 更多