android – Dagger无法在模块上找到注入成员

前端之家收集整理的这篇文章主要介绍了android – Dagger无法在模块上找到注入成员前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在 Android项目中使用 Dagger依赖注入,可以编译和构建应用程序.对象图看起来是正确的和工作的,但是当我添加匕首编译器作为依赖,以便在编译时获取错误,它报告一些奇怪的错误
  1. [ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \
  2. .mgodroid.io.NodeIndexTask> required by com.atami \
  3. .mgodroid.ui.NodeIndexListFragment for com.atami.mgodroid \
  4. .modules.OttoModule
  5. [ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \
  6. .mgodroid.io.NodeTask> required by com.atami \
  7. .mgodroid.ui.NodeFragment for com.atami.mgodroid.modules.OttoModule
  8. [ERROR] error: No injectable members on com.squareup.otto.Bus. Do you want
  9. to add an injectable constructor? required by com.atami. \
  10. mgodroid.io.NodeIndexTaskService for
  11. com.atami.mgodroid.modules.TaskQueueModule

Otto错误看起来像Eric Burke在他的Android App Anatomy演示文稿中提到的没有一个@Provides注释,但是你可以在下面看到.

我的Otto和TaskQueue模块如下:

  1. @Module(
  2. entryPoints = {
  3. MGoBlogActivity.class,NodeIndexListFragment.class,NodeFragment.class,NodeActivity.class,NodeCommentFragment.class,NodeIndexTaskService.class,NodeTaskService.class
  4. }
  5. )
  6. public class OttoModule {
  7.  
  8. @Provides
  9. @Singleton
  10. Bus provideBus() {
  11. return new AsyncBus();
  12. }
  13.  
  14. /**
  15. * Otto EventBus that posts all events on the Android main thread
  16. */
  17. private class AsyncBus extends Bus {
  18. private final Handler mainThread = new Handler(Looper.getMainLooper());
  19.  
  20. @Override
  21. public void post(final Object event) {
  22. mainThread.post(new Runnable() {
  23. @Override
  24. public void run() {
  25. AsyncBus.super.post(event);
  26. }
  27. });
  28. }
  29. }
  30. }

  1. @Module(
  2. entryPoints = {
  3. NodeIndexListFragment.class,NodeTaskService.class
  4. }
  5. )
  6. public class TaskQueueModule {
  7.  
  8. private final Context appContext;
  9.  
  10. public TaskQueueModule(Context appContext) {
  11. this.appContext = appContext;
  12. }
  13.  
  14. public static class IOTaskInjector<T extends Task>
  15. implements TaskInjector<T> {
  16.  
  17. Context context;
  18.  
  19. /**
  20. * Injects Dagger dependencies into Tasks added to TaskQueues
  21. *
  22. * @param context the application Context
  23. */
  24. public IOTaskInjector(Context context) {
  25. this.context = context;
  26. }
  27.  
  28. @Override
  29. public void injectMembers(T task) {
  30. ((MGoBlogApplication) context.getApplicationContext())
  31. .objectGraph().inject(task);
  32. }
  33. }
  34.  
  35. public static class ServiceStarter<T extends Task>
  36. implements ObjectQueue.Listener<T> {
  37.  
  38. Context context;
  39. Class<? extends Service> service;
  40.  
  41. /**
  42. * Starts the provided service when a Task is added to the queue
  43. *
  44. * @param context the application Context
  45. * @param service the Service to start
  46. */
  47. public ServiceStarter(Context context,Class<? extends Service> service) {
  48. this.context = context;
  49. this.service = service;
  50. }
  51.  
  52. @Override
  53. public void onAdd(ObjectQueue<T> queue,T entry) {
  54. context.startService(new Intent(context,service));
  55.  
  56. }
  57.  
  58. @Override
  59. public void onRemove(ObjectQueue<T> queue) {
  60. }
  61. }
  62.  
  63.  
  64. @Provides
  65. @Singleton
  66. TaskQueue<NodeIndexTask> provideNodeIndexTaskQueue() {
  67. ObjectQueue<NodeIndexTask> delegate =
  68. new InMemoryObjectQueue<NodeIndexTask>();
  69. TaskQueue<NodeIndexTask> queue = new TaskQueue<NodeIndexTask>(
  70. delegate,new IOTaskInjector<NodeIndexTask>(appContext));
  71. queue.setListener(new ServiceStarter<NodeIndexTask>(
  72. appContext,NodeIndexTaskService.class));
  73. return queue;
  74. }
  75.  
  76. @Provides
  77. @Singleton
  78. TaskQueue<NodeTask> provideNodeTaskQueue() {
  79. ObjectQueue<NodeTask> delegate =
  80. new InMemoryObjectQueue<NodeTask>();
  81. TaskQueue<NodeTask> queue = new TaskQueue<NodeTask>(
  82. delegate,new IOTaskInjector<NodeTask>(appContext));
  83. queue.setListener(new ServiceStarter<NodeTask>(
  84. appContext,NodeTaskService.class));
  85. return queue;
  86. }
  87. }

  1. /**
  2. * Module that includes all of the app's modules. Used by Dagger
  3. * for compile time validation of injections and modules.
  4. */
  5. @Module(
  6. includes = {
  7. MGoBlogAPIModule.class,OttoModule.class,TaskQueueModule.class
  8. }
  9. )
  10. public class MGoBlogAppModule {
  11. }

解决方法

匕首的全图分析从一个完整的模块中工作.即@Module(complete = true),这是默认值.因为它是默认值,默认情况下,匕首将假定所有绑定都可以从该模块或其明确包含的模块中获得.

在这种情况下,您已经给出了两个声明完整的模块,但是Dagger无法在编译时将这些模块绑定在一起,而无需额外的信号.简而言之,没有OttoModule知道TaskQueueModule,编译器将尝试分析OttoModule的声明完整性,并且失败,因为它现在不关于TaskQueueModule.

修改OttoModule的注释:

  1. @Module(
  2. includes = TaskQueueModule.class,entryPoints = {
  3. MGoBlogActivity.class,NodeTaskService.class
  4. }
  5. )

然后Dagger会知道,为了完成OttoModule,它将其他模块作为其完整定义的一部分.

注意:匕首编译器无法检测到TaskQueueModule在类路径上,只是“知道”开发人员打算将其与OttoModule一起使用,而没有附加信号.例如,您可能有几个模块可以定义任务队列,哪些模块可以选择?声明必须明确.

猜你在找的Android相关文章