Dagger2注入空对象

时间:2018-08-06 17:32:06

标签: android dagger-2

我是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 个答案:

答案 0 :(得分:2)

在TaskModule上创建一个构造函数,并传递此参数taskDataRepository和视图,然后在TaskModule上使用它。所以您的初始化应该像这样

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

答案 1 :(得分:0)

您应该提供存储库并查看您的模块,以便注入工作。有两种方法可以解决您的问题:

  1. 使用模块参数(不建议)

    @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);

      ... ...
    }
  1. 使用@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注释,因此我们也可以将模块方法更改为静态方法:

@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

希望有帮助