New Dagger2 Integration with Android Architecture component

Sharing is caring!

In my last tutorial, we had functioned with Dagger2 in android application development. Dagger 2 is an awesome dependency injection library which provides the alternative way of Object instantiation. I already explained what is Dagger2 and why we are using this in android application development and what are the benefits of using this? Here is the detail of Dagger2 dependency injection with Android.

In this tutorial, we will learn to integrate the new Dagger2 with android architecture component. Implementation of Dagger2 with android architecture is slite changed. It provides much more fanciable and easy to provide the instance. The very first thing we need to add the relevant dependencies in your android build.gradle file.

ext {
    daggerVersion = '2.11'  
  
    dagger = "com.google.dagger:dagger:$daggerVersion"
    daggerCompiler = "com.google.dagger:dagger-compiler:$daggerVersion"
    daggerAndroid = "com.google.dagger:dagger-android:$daggerVersion"
}

Android architecture design is based on the view model. So Every module will inject with view model by Dagger2. Now in the next step, we need to get the activity injector in the main application (An Application that injects its members and can be used to inject Activities, Fragments, Services, BroadcastReceivers and ContentProviders attached to it.).

We have already checked with the old way instantiation of an object, here is an example of a sample.

private void injectDependency() {
        ApplicationComponent applicationComponent = ((MainApplication) getActivity().getApplication()).getApplicationComponent();
        ArticleComponent articleComponent = DaggerArticleComponent.builder()
                .applicationComponent(applicationComponent)
                .articleModule(new ArticleModule())
                .build();
        articleComponent.inject(this);
    }

Ok, let’s implement new Dagger2 injection. We need to initialize the Dagger2 component in Main Application by implementing new HasActivityInjector (Provides an AndroidInjector of Activitys.)

public class MainApplication extends Application implements HasActivityInjector{

    @Inject
    DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        initializeComponent();
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return activityDispatchingAndroidInjector;
    }

    private void initializeComponent() {
        DaggerAppComponent.builder()
                .application(this)
                .build()
                .inject(this);
    }
}

Dagger2 introduced some of the new component builders. Let’s see in detail.

@ContributesAndroidInjector (module) and @ContributesAndroidInjector

If an activity builder module containing any Fragment or view then we can provide the specific Fragment module to contribute for the android injector and if not then simply annotated with @ContributesAndroidInjector. To mapping all activity and pass it to Dagger2 we will create the ActivityBuilderModule.

@Module
public abstract class ActivityBuilderModule {

    @ContributesAndroidInjector(modules = FragmentBuilderModule.class)
    abstract MainActivity mainActivity();

    @ContributesAndroidInjector
    abstract MovieDetailActivity movieDetailActivity();
}

Dagger know our activities in compile time. In our app, we have Main and Detail activity. So we map both activities here.

@Componentand @Component.Builder

A component will provide injected instances by using modules. Component.Builder used for instantiation of a component. We can create the interface of the builder and annotate with @Component.Builder and build by @BindInstance.

@Singleton
@Component(modules = {AppModule.class, AndroidInjectionModule.class, ActivityBuilderModule.class})
public interface AppComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

    void inject(MainApplication aaApp);
}

AppModule: App Module provides retrofit, okhttp, persistence DB, shared pref etc here. So our dagger graph will understand that.

@Module(includes = ViewModelModule.class)
public class AppModule {

    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient() {
        OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
        okHttpClient.connectTimeout(Constant.TIMEOUT_IN_SEC, TimeUnit.SECONDS);
        okHttpClient.readTimeout(Constant.TIMEOUT_IN_SEC, TimeUnit.SECONDS);
        okHttpClient.addInterceptor(new RequestInterceptor());
        return okHttpClient.build();
    }

    @Provides
    @Singleton
    ApiServices provideRetrofit(OkHttpClient okHttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.ENDPOINT)
                .addConverterFactory(GsonConverterFactory.create())
                .client(okHttpClient)
                .build();

        return retrofit.create(ApiServices.class);
    }

    @Provides
    @Singleton
    MovieDatabase provideMovieDatabase(Application application) {
        return Room.databaseBuilder(application, MovieDatabase.class, "aa.db").build();
    }

    @Provides
    @Singleton
    MovieDao provideMovieDao(MovieDatabase movieDatabase) {
        return movieDatabase.movieDao();
    }

}

ViewModelModule: VewModelModule has all the module information about the each ViewModel and injects those when we required.

@Module
public abstract class ViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(MovieListViewModel.class)
    abstract ViewModel bindsMovieListViewModel(MovieListViewModel movieListViewModel);

    @Binds
    @IntoMap
    @ViewModelKey(MovieDetailViewModel.class)
    abstract  ViewModel bindsMovieDetailViewModel(MovieDetailViewModel movieDetailViewModel);

    @Binds
    abstract ViewModelProvider.Factory bindsViewModelFactory(MovieViewModelFactory movieViewModelFactory);
}

We can inject MovieListViewModel by annotated @Inject.

 @Inject
    MovieListViewModel movieListViewModel;

Now in the last activity and Fragment should know that how Dagger injected. So we need to tell by AndroidInjection.inject() method in onCreate() of Activity or onAttach() of Fragment.

public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector{

    @Inject
    DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;
  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
       
    }

    @Override
    public AndroidInjector<Fragment> supportFragmentInjector() {
        return fragmentDispatchingAndroidInjector;
    }
}

Wrapping up: Ok, You have done so for. The conclusion is that It does not matter how many class files need to create the most important that our code will be in well structured and we do not worry about any refactor or changes in code in future.  I used the article reference here.

Here is the Github link for an Android Architecture Sample project.

Please do subscribe email to get all newsletters of this blog and if you feel that this post will help you to better understand then do not forget to subscribe, share and comment below. Ok, then I will see you in my next tutorial till then enjoy your life and happy coding 🙂

0 0 votes
Article Rating
New Dagger2 Integration with Android Architecture component
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Nice tutorial and sample app, very useful Thanks

admin

Thanks Jaime

Heri Setiawan

nice tutorial,
i have question, how you implemen Broadcastreciver with Dagger 2?

Scroll to top
4
0
Would love your thoughts, please comment.x
()
x