7 steps to implement Dagger 2 in Android

Anitaa Murthy
AndroidPub
Published in
6 min readDec 23, 2018

--

So I finally got a chance to explore the new Dagger 2 in a project recently. And while there are a lot of resources online about what is Dagger and why dagger 2 is necessary and how to implement Dagger 2, I found that there was a steep learning curve to it. While I understood why dagger 2 is not only necessary but a must in some cases, I found practical implementation difficult. So I thought I would write about the 7 basic steps to implement Dagger 2 in an Android app.

Note: This article focuses on implementation of dagger using the new dagger android injection.

I chose to build a simple movies app to test the dagger implementation. This is the app.

This app displays a list of movies or tv shows from the famous TMDB api. There is a details page which displays the movie or tv show videos, reviews, cast and crew info etc. We are going to build a simplified version of this app. i.e. we are going to focus on building a single screen app that fetches a list of movies from the TMDB api and displays it in the app.

For those of you interested in skipping the article, the GitHub link is for this implementation is here.

  • The master branch — code in Java
  • The kotlin_support branch — code in Kotlin

So let’s begin!

Step 1: Add the necessary dependencies to the app

Java:

Kotlin:

add kotlin support first in build.gradle
app/build.gradle

Step 2: Configure Room

Next thing we have to do is setup Room database in the app. This involves:

1. Creating an Entity:

MovieEntity.java:

MovieEntity.kt:

2. Creating Dao class:

MovieDao.java:

MovieDao.kt:

3. Creating the Database:

AppDatabase.java:

AppDatabase.kt:

Note: If you would like to know more about Room persistence Library and how to configure it, then checkout this article

Step 3: Configure Api Service:

Now that we have setup the local database, we need to configure the api service system. We are going to use Retrofit for that. This involves:

1. Creating a rest api response model:

MovieApiResponse.java:

MovieApiResponse.kt:

2. Creating a rest api service:

MovieApiService.java:

MovieApiService.kt:

Step 4: Configure Repository class

The repository classes are responsible for handling data operations. For instance, the first time the app is opened, the data will be fetched from the backend api service and stored locally in room. But if there is no internet or the api service is down, the data will be fetched from the local cache. So this class will choose which data sources to use to get the data.

MovieRepository.java:

MovieRepository.kt:

Step 5: Configure the ViewModel class

As mentioned in the previous step:

  • The repository class is responsible for fetching the data (either from web api or local cache).
  • The ViewModel is responsible for updating the UI with the data changes. The ViewModel will initialise an instance of the Repository class and update the UI based with this data.

For this, the ViewModel must have access to the usingMovieDaoclass and the MovieApiService class. This is where Dagger comes in. We will be injecting the ViewModel with the MovieDao class and the MovieApiService class.

Now, let’s setup the ViewModel class.

MovieListViewModel.java:

MovieListViewModel.kt:

Step 5: Configure Dagger (finally!)

Now let’s create some Dagger classes.

In Dagger, we can annotate classes with @Module. These classes are responsible for providing objects/classes which can be injected. Such classes can define methods annotated with @Provides. The returned objects from these methods are available for dependency injection.

So in our case, we need to inject two classes: MovieDao class and MovieApiService class. So we are going to create two Modules: ApiModule and DbModule (This can be done in a single module but I prefer to keep local and web service separate).

1. ApiModule class

ApiModule.java

ApiModule.kt

2. DbModule class

DbModule.java

DbModule.kt

3. ViewModelFactory class:

Now we need to inject these two modules into our ViewModel. ViewModelFactory class basically helps you dynamically create ViewModels for your Activities and Fragments. The ViewModelFactoryclass has a list of providers and can create any ViewModel that was bound. Fragments and Activities can now just inject the factory and retrieve their ViewModel.

ViewModelFactory.java

ViewModelFactory.kt

4. ViewModelKey class:

ViewModelKeys helps you map your ViewModel classes so ViewModelFactory can correctly provide/inject them.

ViewModelKey.java

ViewModelKey.kt

4. ViewModelModule class

The ViewModelModule is used to provide a map of view models through dagger that is used by the ViewModelFactory class.

ViewModelModule.java

ViewModelModule.kt

So basically,

  • We can use the ViewModelModule to define our ViewModels.
  • We provide a key for each ViewModel using the ViewModelKey class.
  • Then in our Activity/Fragment, we use the ViewModelFactory class to inject the corresponding ViewModel. (We will look into more detail at this when we are creating our Activity).

5. ActivityModule class

Since we are using the dagger-android support library, we can make use of Android Injection. The ActivityModule generates AndroidInjector(this is the new dagger-android class which exist in dagger-android framework) for Activities defined in this class. This allows us to inject things into Activities using AndroidInjection.inject(this) in the onCreate() method.

ActivityModule.java

ActivityModule.kt

Note: We can define all of the Activity which require injecting. For instance, in our case, this will generate AndroidInjector<MainActivity>.

6. AppComponent class

Any class with the annotation @Component defines the connection between the modules and the classes which need the dependency. We define a @Component.Builder interface which will be called from our custom Application class. This will set our application object to the AppComponent. So inside the AppComponent the application instance is available. So this application instance can be accessed by our modules such as ApiModule when needed.

AppComponent.java

AppComponent.kt

Step 6: Configure Application class

So now we create a custom Application class in our project.

AppController.java

AppController.kt

Note: Don’t forget to add this custom Application class to the AndroidManifest.xml

<application
android:name=".AppController"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"/>

Step 7: Configure MainActivity class

So now we need to create our Activity class.

MainActivity.java

MainActivity.kt

Note: I am not including the implementation of the xml classes or the RecyclerView adapter classes here as it is not part of the scope of this article. You can checkout this Github project to know the detailed implementation.

And that’s it! We build and run our app and this is the output we should receive.

Note: If you would like to know how to implement the BackgroundSwitcherView i.e. change the background of the activity when the recyclerView is scrolled, checkout this link.

Bonus:

We saw how to inject the ViewModelFactory into our MainActivity. If you would like to inject the ViewModelFactory into a Fragment, we need to do the following modifications:

1. FragmentModule class:

Create a new class called FragmentModule.

FragmentModule.java

FragmentModule.kt

2. Modify ActivityModule class:

Add the newly created FragmentModule to whichever Activity you want to inject. i.e. in our case MainActivity.

ActivityModule.java

ActivityModule.kt

3. Modify MainActivity class:

We need to implement HasSupportFragmentInjector in our Activity if we want to inject the ViewModelFactory class in our Fragment. And also, move all our RecyclerView.Adapter and ViewModel implementation to the Fragment class.

MainActivity.java

MainActivity.kt

4. Add MovieFragment class:

Lastly, we need to create our Fragment class. We inject the ViewModelFactory into the Fragment and initialise the viewModel. The remaining implementation is the same.

MovieListFragment.java

MovieListFragment.kt

5. Add FragmentModule class to AppComponent:

@Component(
modules = [
ApiModule::class,
DbModule::class,
ViewModelModule::class,
ActivityModule::class,
FragmentModule::class,
AndroidSupportInjectionModule::class]
)

You can checkout this commit to find out the differences between injecting into Activity and injecting into fragment for Java and this commit for Kotlin.

And that’s it! 😄. I know it feels overwhelming and kinda a lot of work but in the end it’s worth it, I think.

You can find the GitHub link for this sample implementation here:

  • The master branch — contains Dagger implementation in Activity in Java.
  • The kotlin_support branch — contains Dagger implementation in Activity in Kotlin.

Fragment injection implementation can be found under:

For those of you interested in the whole app implementation, (and not just the simplified version we implemented here), you can checkout the Github project from here.

The master branch — code in Java

The kotlin_support branch — code in Kotlin

I hope you enjoyed this article and found it useful, if so please hit the Clap button. Let me know your thoughts in the comments section.

Happy coding! Thanks for reading!

--

--