Search code examples
javaandroiddagger-2dagger

How to extend the Google android architecture dagger sample?


Google Repo Link. All of the boilerplate code is taken from there.

I just can't figure out how to add my own dependencies to this architecture. I want to do the following things:

  1. I need to use one of the presenters in a non-fragment class.
  2. I need to add a network module, which provides a simple OkHttp client.

I understand dagger in general, but dagger-android confuses me in many parts..

ToDoApplication:

public class ToDoApplication extends DaggerApplication {
    @Inject
    TasksRepository tasksRepository;

    @Inject
    AsyncTask asyncTask;

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerAppComponent.builder().application(this).build();
    }
}

AppComponent:

@Singleton
@Component(modules = {TasksRepositoryModule.class,
        ApplicationModule.class,
        ActivityBindingModule.class,
        AndroidSupportInjectionModule.class})
public interface AppComponent extends AndroidInjector<ToDoApplication> {

    TasksRepository getTasksRepository();
    AsyncTask getAsyncTask();

    @Component.Builder
    interface Builder {

        @BindsInstance
        AppComponent.Builder application(Application application);

        AppComponent build();
    }
}

ApplicationModule:

@Module
public abstract class ApplicationModule {
    //expose Application as an injectable context
    @Binds
    abstract Context bindContext(Application application);
}

ActivityBindingModule:

@Module
public abstract class ActivityBindingModule {
    @ActivityScoped
    @ContributesAndroidInjector(modules = TasksModule.class)
    abstract TasksActivity tasksActivity();

    @ActivityScoped
    @ContributesAndroidInjector(modules = AddEditTaskModule.class)
    abstract AddEditTaskActivity addEditTaskActivity();

    @ActivityScoped
    @ContributesAndroidInjector(modules = StatisticsModule.class)
    abstract StatisticsActivity statisticsActivity();

    @ActivityScoped
    @ContributesAndroidInjector(modules = TaskDetailPresenterModule.class)
    abstract TaskDetailActivity taskDetailActivity();
}

ExampleModule:

@Module
public abstract class TasksModule {
    @FragmentScoped
    @ContributesAndroidInjector
    abstract TasksFragment tasksFragment();

    @ActivityScoped
    @Binds abstract TasksContract.Presenter taskPresenter(TasksPresenter presenter);
}

ExampleActivity:

public class TasksActivity extends DaggerAppCompatActivity {
 @Inject
    TasksPresenter mTasksPresenter;
    @Inject
    Lazy<TasksFragment> taskFragmentProvider;

...

Example Fragment:

@ActivityScoped
public class TasksFragment extends DaggerFragment implements TasksContract.View {

    @Inject
    TasksContract.Presenter mPresenter;

...

Example Presenter:

@ActivityScoped
final class TasksPresenter implements TasksContract.Presenter {

    @Inject
    TasksPresenter(TasksRepository tasksRepository) {
        mTasksRepository = tasksRepository;
    }

...

The code above is all correctly working. Now my problem:

  1. I have an AsyncTask, which needs a presenter to post something in it's onPostExecute method. I injected the presenter, but I get the error that the presenter is not initialized.

  2. I added the following NetworkModule to the module array in @Component and simply injected it in the AsyncTask, but it's not working (error: ... not initialized). What else would I have to add?

NetworkModule:

@Module
class NetworkModule {

    @Provides
    @Singleton
    fun provideOkHttp(): OkHttpClient {
        return OkHttpClient()
    }
}

AsyncTask

private class MyAsyncTask extends AsyncTask<String, Integer, Long> {

     @Inject 
     TasksPresenter presenter;
     @Inject
     OkHttpClient client;

     protected Long doInBackground(String... params) {
         client.doSomething();
         ...
     }


     protected void onPostExecute(Long result) {
         ...
         presenter.doSomething();
     }
 }

All of my code is correctly working without dagger so you don't have to worry about it. :)

I hope somebody can help me. If you have further questions feel free to ask!


Solution

  • I fixed it by using constructor injection for the AsyncTask and only passing the Okhttp client in the constructor. I no longer inject the presenter in the AsyncTask, instead I used this to return a value from the AsyncTask to the presenter.