Android

New Dagger2 Integration with Android Architecture component

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

Recent Posts

Hide your production API key or any sensitive data in Android

Hi everyone, In this article, we are going to learn how to hide the production… Read More

2 years ago

How to handle the localisation or multi language support in android with examples?

Hello everyone, Today in this article, we are going to learn about localisation to support… Read More

2 years ago

How to convert any callback to Coroutines and use them in Kotlin Android?

Hello everyone, In this article, we are going to learn something to handle the callback… Read More

2 years ago

Request Permission Launcher with Kotlin in Android

In this article, we are learning about the run time permissions for request permission launchers.… Read More

2 years ago

Implement the SMS User Consent API and SMS Retriever API in Android

Hello everyone. In my last tutorial, we learned about the Jetpack Compose introduction and about applying the… Read More

3 years ago

Jetpack Compose Coroutine flow with LiveData/ViewModel in Android

Hello everyone, In this article, we are going to learn about the Jetpack Compose with… Read More

3 years ago