gpt4 book ai didi

android - Dagger 在模块上找不到可注入(inject)成员

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:57:45 25 4
gpt4 key购买 nike

我正在使用 Dagger用于在 Android 项目中进行依赖注入(inject),并且可以很好地编译和构建应用程序。对象图看起来是正确的并且可以工作,但是当我添加 dagger-compiler 作为依赖项以在编译时出错时,它会报告一些奇怪的错误:

[ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \
.mgodroid.io.NodeIndexTask> required by com.atami \
.mgodroid.ui.NodeIndexListFragment for com.atami.mgodroid \
.modules.OttoModule
[ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \
.mgodroid.io.NodeTask> required by com.atami \
.mgodroid.ui.NodeFragment for com.atami.mgodroid.modules.OttoModule
[ERROR] error: No injectable members on com.squareup.otto.Bus. Do you want
to add an injectable constructor? required by com.atami. \
mgodroid.io.NodeIndexTaskService for
com.atami.mgodroid.modules.TaskQueueModule

Otto 错误看起来像 Eric Burke 在他的 Android App Anatomy 中提到的错误关于没有 @Provides 注释的演示,但正如您在下面看到的,我有。

我的Otto和TaskQueue模块如下:

@Module(
entryPoints = {
MGoBlogActivity.class,
NodeIndexListFragment.class,
NodeFragment.class,
NodeActivity.class,
NodeCommentFragment.class,
NodeIndexTaskService.class,
NodeTaskService.class
}
)
public class OttoModule {

@Provides
@Singleton
Bus provideBus() {
return new AsyncBus();
}

/**
* Otto EventBus that posts all events on the Android main thread
*/
private class AsyncBus extends Bus {
private final Handler mainThread = new Handler(Looper.getMainLooper());

@Override
public void post(final Object event) {
mainThread.post(new Runnable() {
@Override
public void run() {
AsyncBus.super.post(event);
}
});
}
}
}

...

@Module(
entryPoints = {
NodeIndexListFragment.class,
NodeFragment.class,
NodeIndexTaskService.class,
NodeTaskService.class
}
)
public class TaskQueueModule {

private final Context appContext;

public TaskQueueModule(Context appContext) {
this.appContext = appContext;
}

public static class IOTaskInjector<T extends Task>
implements TaskInjector<T> {

Context context;

/**
* Injects Dagger dependencies into Tasks added to TaskQueues
*
* @param context the application Context
*/
public IOTaskInjector(Context context) {
this.context = context;
}

@Override
public void injectMembers(T task) {
((MGoBlogApplication) context.getApplicationContext())
.objectGraph().inject(task);
}
}

public static class ServiceStarter<T extends Task>
implements ObjectQueue.Listener<T> {

Context context;
Class<? extends Service> service;

/**
* Starts the provided service when a Task is added to the queue
*
* @param context the application Context
* @param service the Service to start
*/
public ServiceStarter(Context context,
Class<? extends Service> service) {
this.context = context;
this.service = service;
}

@Override
public void onAdd(ObjectQueue<T> queue, T entry) {
context.startService(new Intent(context, service));

}

@Override
public void onRemove(ObjectQueue<T> queue) {
}
}


@Provides
@Singleton
TaskQueue<NodeIndexTask> provideNodeIndexTaskQueue() {
ObjectQueue<NodeIndexTask> delegate =
new InMemoryObjectQueue<NodeIndexTask>();
TaskQueue<NodeIndexTask> queue = new TaskQueue<NodeIndexTask>(
delegate, new IOTaskInjector<NodeIndexTask>(appContext));
queue.setListener(new ServiceStarter<NodeIndexTask>(
appContext, NodeIndexTaskService.class));
return queue;
}

@Provides
@Singleton
TaskQueue<NodeTask> provideNodeTaskQueue() {
ObjectQueue<NodeTask> delegate =
new InMemoryObjectQueue<NodeTask>();
TaskQueue<NodeTask> queue = new TaskQueue<NodeTask>(
delegate, new IOTaskInjector<NodeTask>(appContext));
queue.setListener(new ServiceStarter<NodeTask>(
appContext, NodeTaskService.class));
return queue;
}
}

...

/**
* Module that includes all of the app's modules. Used by Dagger
* for compile time validation of injections and modules.
*/
@Module(
includes = {
MGoBlogAPIModule.class,
OttoModule.class,
TaskQueueModule.class
}
)
public class MGoBlogAppModule {
}

最佳答案

Dagger 的全图分析从一个完整的模块开始工作。即@Module(complete = true),这是默认的。因为它是默认设置,所以默认情况下,dagger 将假定所有绑定(bind)都可从该模块或它显式包含的那些模块中获得。

在这种情况下,您已经提供了两个您声称已完成的模块,但 Dagger 无法在没有额外信号的情况下在编译时将它们连接在一起。简而言之,在 OttoModule 不知道 TaskQueueModule 的情况下,编译器将尝试分析 OttoModule 的完整性,但会失败,因为它现在不了解 TaskQueueModule。

修改 OttoModule 的注解:

@Module(
includes = TaskQueueModule.class,
entryPoints = {
MGoBlogActivity.class,
NodeFragment.class,
NodeActivity.class,
NodeCommentFragment.class,
NodeIndexTaskService.class,
NodeTaskService.class
}
)

然后 Dagger 将知道要使 OttoModule 完整,它将另一个模块作为其完整定义的一部分。

注意:dagger-compiler 无法检测到 TaskQueueModule 存在于类路径中,只是“知道”开发人员打算将其与 OttoModule 一起使用而无需那个额外的信号。例如,您可能有多个定义任务队列的模块,它会选择哪一个?声明必须明确。

关于android - Dagger 在模块上找不到可注入(inject)成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14695515/

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