Android 匕首罐';在模上找不到可注入成员
我在一个Android项目中使用依赖注入,可以很好地编译和构建应用程序。对象图看起来是正确的,并且工作正常,但是当我添加dagger编译器作为一个依赖项以在编译时获取错误时,它报告了一些奇怪的错误:Android 匕首罐';在模上找不到可注入成员,android,dependency-injection,dagger,Android,Dependency Injection,Dagger,我在一个Android项目中使用依赖注入,可以很好地编译和构建应用程序。对象图看起来是正确的,并且工作正常,但是当我添加dagger编译器作为一个依赖项以在编译时获取错误时,它报告了一些奇怪的错误: [ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \ .mgodroid.io.NodeIndexTask> required by com.atami \ .mgodroid.ui.N
[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
Dagger的完整图形分析从一个完整的模块开始工作。i、 e.@Module(complete=true),这是默认值。由于这是默认设置,dagger在默认情况下会假定所有绑定都可以从该模块或它显式包含的模块中获得 在本例中,您已经给出了两个您声称已完成的模块,但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编译器无法检测到TaskQueueModule位于类路径上,只需“知道”开发人员打算在没有额外信号的情况下将其与OttoModule一起使用即可。例如,您可能有几个模块定义任务队列,它会选择哪一个?声明必须明确。什么定义模块为“完整”?现在我有一个总线和一个TaskQueue被注入到同一个类中,但是一个总线没有被注入到TaskQueue中。在我看来,TaskQueue并没有直接与OttoModule一起使用。也许更好的问题是,一个模块是否应该包含一个对象的所有依赖项才能完整?或者,如果一个模块包含一种类型的依赖关系,那么多个模块向同一组对象提供依赖关系,就像我上面所说的那样?如果可以通过@Provides方法本身找到满足其入口点需要的所有绑定,那么模块就是完整的,@在显式
包含的模块中提供方法,或在可发现的可注入类(带有@Inject字段或构造函数的类)中提供方法。这让我很困惑,我没有意识到模块必须满足其入口点中的每个绑定。我的印象是,如果在创建对象图之后解决了每个绑定,那么模块将是“完整的”,即使现在我键入了它,这没有任何意义。感谢您的帮助澄清!我很高兴您提到没有@提供
注释,因为我的错误是我在其中一个模块中忘记了它。
@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 {
}
@Module(
includes = TaskQueueModule.class,
entryPoints = {
MGoBlogActivity.class,
NodeFragment.class,
NodeActivity.class,
NodeCommentFragment.class,
NodeIndexTaskService.class,
NodeTaskService.class
}
)