gpt4 book ai didi

android - Dagger 2 : Unable to inject dependencies in WorkManager

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:32:46 26 4
gpt4 key购买 nike

所以据我了解,Dagger 还不支持在 Worker 中注入(inject)。但是正如人们所建议的那样,有一些解决方法。我已经尝试按照在线示例通过多种方式来做到这一点,但它们都不适合我。

当我不尝试向 Worker 类中注入(inject)任何东西时,代码工作正常,只是我不能做我想做的事,因为我需要访问一些 DAO 和服务。如果我在这些依赖项上使用 @Inject,则依赖项要么为 null,要么 worker 永远不会启动,即调试器甚至不会进入 Worker 类。

例如,我尝试这样做:

@Component(modules = {Module.class})
public interface Component{

void inject(MyWorker myWorker);
}

@Module
public class Module{

@Provides
public MyRepository getMyRepo(){
return new myRepository();
}

}

在我的 worker 身上

@Inject
MyRepository myRepo;

public MyWorker() {
DaggerAppComponent.builder().build().inject(this);
}

但是执行永远不会到达 worker 。如果我删除构造函数,myRepo 依赖项将保持为空。

我尝试了很多其他的事情,但都没有用。有没有办法做到这一点?谢谢!!

最佳答案

概览

你需要看看WorkerFactory , 可从 1.0.0-alpha09 获得继续。

以前的解决方法依赖于能够创建 Worker使用默认的 0-arg 构造函数,但从 1.0.0-alpha10 开始这不再是一种选择。

例子

假设您有一个 Worker子类称为 DataClearingWorker , 这个类需要一个 Foo来自你的 Dagger 图。

class DataClearingWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {

lateinit var foo: Foo

override fun doWork(): Result {
foo.doStuff()
return Result.SUCCESS
}
}

现在,您不能只实例化其中一个 DataClearingWorker直接实例。所以你需要定义一个WorkerFactory可以为您创建其中之一的子类;不仅要创建一个,还要设置你的 Foo领域也是如此。

class DaggerWorkerFactory(private val foo: Foo) : WorkerFactory() {

override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? {

val workerKlass = Class.forName(workerClassName).asSubclass(Worker::class.java)
val constructor = workerKlass.getDeclaredConstructor(Context::class.java, WorkerParameters::class.java)
val instance = constructor.newInstance(appContext, workerParameters)

when (instance) {
is DataClearingWorker -> {
instance.foo = foo
}
// optionally, handle other workers
}

return instance
}
}

最后,您需要创建一个 DaggerWorkerFactory可以访问 Foo .您可以使用正常 Dagger 方式执行此操作。

@Provides
@Singleton
fun workerFactory(foo: Foo): WorkerFactory {
return DaggerWorkerFactory(foo)
}

禁用默认 WorkManager 初始化

您还需要禁用默认 WorkManager初始化(自动发生)并手动初始化。

如何执行此操作取决于 androidx.work 的版本你正在使用:

2.6.0 及以后:

AndroidManifest.xml , 添加:

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="YOUR_APP_PACKAGE.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>

2.6.0 之前:

AndroidManifest.xml , 添加:

 <provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="YOUR_APP_PACKAGE.workmanager-init"
android:enabled="false"
android:exported="false"
tools:replace="android:authorities" />

请务必将 YOUR_APP_PACKAGE 替换为您的实际应用程序包。 <provider上面的 block inside 你的 <application标记.. 所以它是你的 Activities 的 sibling , Services等等……

在你的Application子类,(或其他地方,如果你愿意),你可以手动初始化 WorkManager .

@Inject
lateinit var workerFactory: WorkerFactory

private fun configureWorkManager() {
val config = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()

WorkManager.initialize(this, config)
}

关于android - Dagger 2 : Unable to inject dependencies in WorkManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52434165/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com