首页 文章

Dagger2注入空对象

提问于
浏览
0

我是Dagger的新手,并试图将dagger2用于DI,但看起来它为我的活动注入了一个空的演示者 . 以下是我的代码 .

公共类TasksActivity扩展AppCompatActivity {

@Inject
TasksContract.Presenter mTasksPresenter;
......

@Override
protected void onCreate(Bundle savedInstanceState) {
    ... ...

    DaggerTasksComponent.builder()
            .appComponent(MyApp.getAppComponent())
            .tasksModule(new TasksModule())
            .build()
            .inject(this);

   ... ...
}

TasksActivity模块:

@Module
    public class TasksModule {

    @Provides
    @ActivityScoped
    TasksContract.Presenter providePresenter(TaskDataRepository taskDataRepository, TasksContract.View view) {
        return new TasksPresenter(taskDataRepository, view);
    }

    @Provides
    @ActivityScoped
    TasksContract.View provideView() {
        return new TasksFragment();
    }
}

TasksActivity的组件:

@ActivityScoped
    @Component (modules = TasksModule.class, dependencies = AppComponent.class)
    public interface TasksComponent {
        void inject(TasksActivity activity);
    }

我还有一个用于应用程序级依赖注入的AppModule和AppComponent,例如TaskDataRepository . 并用@Singleton注释它们 .

2 回答

  • 2

    在TaskModule上创建一个构造函数,传递这个参数taskDataRepository和view,然后在TaskModule上使用它 . 所以你的初始化应该是这样的

    DaggerTasksComponent.builder()
                .appComponent(MyApp.getAppComponent())
                .tasksModule(new TasksModule(taskDataRepository, view))
                .build()
                .inject(this);
    
  • 0

    您应该为模块提供存储库和视图,以便注入工作 . 在你的情况下,有两种方法可以做到:

    • 使用模块参数(不建议)
    @Module
    public class TasksModule {
    
    private final TaskDataRepository taskDataRepository;
    private final TasksContract.View view;
    
    public TasksModule(TaskDataRepository taskDataRepository, TasksContract.View view){
    this.taskDataRepository = taskDataRepository;
    this.view = view;
    

    }

    @Provides
    @ActivityScoped
    TasksContract.Presenter providePresenter(TaskDataRepository taskDataRepository, TasksContract.View view) {
        return new TasksPresenter(taskDataRepository, view);
    }
    
    @Provides
    @ActivityScoped
    TasksContract.View provideView() {
        return new TasksFragment();
    }
    

    }

    然后您的构建组件的活动代码将如下所示:

    @Override
        protected void onCreate(Bundle savedInstanceState) {
        ... ...
    
        DaggerTasksComponent.builder()
            .appComponent(MyApp.getAppComponent())
            .tasksModule(new TasksModule(new TaskDataRepository(), new TasksFragment()))
            .build()
            .inject(this);
    
          ... ...
        }
    
    • 使用 @BindsInstance 注释(首选):

    为了使用bindsInstance,您可以稍微更改您的活动组件:

    @ActivityScoped
    @Component (modules = TasksModule.class, dependencies = AppComponent.class)
    public interface TasksComponent {
        void inject(TasksActivity activity);
    
        @Component.Builder
        interface Builder {
            @BindsInstance Builder taskRepository(TaskDataRepository taskDataRepository);
            @BindsInstance Builder activity(TaskActivity activity);
            TasksComponent build();
      }
    }
    

    因为我们正在使用bindsInstance注释,所以我们也可以将模块方法更改为static:

    @Module
    public abstract class TasksModule {
    
    @Provides
    @ActivityScoped
    static TasksContract.Presenter providePresenter(TaskDataRepository taskDataRepository, TasksContract.View view) {
        return new TasksPresenter(taskDataRepository, view);
    }
    
    @Provides
    @ActivityScoped
    static TasksContract.View provideView() {
        return new TasksFragment();
    }
    }
    

    最后,您的组件构建器将如下所示:

    DaggerTasksComponent.builder()
        .appComponent(MyApp.getAppComponent())
        .activity(this)
        .taskRepository(new TaskDataRepository())
        .build()
        .inject(this);
    

    进一步阅读请参考docs和其他samples

    希望它有所帮助

相关问题