How-to Dagger 2 with Android: Part 1

John Tucker
ProAndroidDev
Published in
4 min readNov 26, 2017

We scratch the surface of the Dagger 2 dependency injection framework through a simple singleton example.

First we need to know what Dagger 2 is:

Dagger is a fully static, compile-time dependency injection framework for both Java and Android. It is an adaptation of an earlier version created by Square and now maintained by Google.

Dagger Team

With this you then need to know what dependency injection is. I found a particularly helpful article: An Absolute Beginner’s Tutorial on Dependency Inversion Principle, Inversion of Control and Dependency Injection.

We will implement two applications that have the same functional behavior; they display the time the application started. The first example will not use dependency injection (no Dagger 2) and second will (with Dagger 2).

In both cases, we will create a singleton that, when constructed, stores the date as a long (number of milliseconds since January 1, 1970 0:00 GMT). Its getDate method returns that date (long).

Not Dependency Injection

This example is available:

The application consists of a singleton (following a classic pattern), MyExample (MyExample.java), and an activity that depends on it, MainActivity.

Observations:

  • You can confirm that MyExample is a singleton by rotating the device; even though the activity is destroyed and recreated, the same date shows.
  • MainActivity is dependent on the concrete implementation MyExample.

Dependency Injection

This example is available:

It took me awhile to piece together this example from multiple tutorials; most were either a too complicated or their code just did not run. Let us walk through how it was built (introducing Dagger 2 concepts along the way).

Using Android Studio 3.X to create a new project (with a basic activity), I first followed the instructions to add Dagger 2 dependencies to it. Basically amounts to adding two lines to the application’s dependencies:

Observations:

  • The latest version, as of this writing, is 2.13; feel free to update it to the latest release.
  • In this example, we are not injecting any Android objects (e.g., Fragments); thus we do not need any of the dagger-android-X dependencies.

Next, I did one thing unrelated to dependency injection. I set an id, tvDate, on the TextView in the resource file and referenced it in the activity.

Because we want MainActivity to depend on an interface and not a concrete implementation, I created an interface with a getDate method. The broad idea here is that we will inject in the concrete implementation of this interface.

I then implemented a class; notice none of the singleton code is here.

We now introduce our first Dagger 2 concept; a Module. A Module defines one or more injectable classes (as denoted by the Provides annotation). In this trivial case, I have provided the single concrete implementation of MyExampleImpl as an interface MyExample. In this case, I also used the Singleton annotation to ensure that our application only uses one shared instance of a class implementing MyExample.

The next Dagger 2 concept is a Component. A Component is a mapping between one or more modules and one or more classes that will use them. In this particular case, we have a single module, MyModule, that is being used by a single class, MainActivity.

note: Because a referenced module provides a singleton, the Component itself must be flagged with the Singleton annotation. The explanation for this involves scopes and lifecycles as in the official documentation (it still does not make sense to me).

During compilation, Dagger 2 creates concrete class implementations triggered on the Component interfaces with names prefixed with Dagger, e.g., DaggerMyComponent in this case. As our application first starts, we need to instantiate these classes and store them for use throughout our application. We can extend Application for this purpose and update our AndroidManifest.xml to use it.

Observations:

  • Because Dagger 2 creates the DaggerMyComponent classes during compilation, your IDE will complain about missing a reference at first.
  • I still do not fully understand what each of the individual calls, e.g, builder, etc. are doing. Right now, I see this as boilerplate code that I need to use to make it work.

With all this in place, we can now can get a reference to the implemented singleton in MainActivity by using the Inject annotation and a call to the Component’s inject method. Again, the Component is stored in the Application instance.

Observations:

  • Normally, I would have made the mMyExample member private; Dagger 2, however, cannot inject into private members.
  • We have accomplished our goal. MainActivity only depends on the interface MyExample, the precise implementation is managed externally using Dagger 2.

Next Steps

Turns out that dependency injection is a bit more complicated than I originally thought. In the next article, How-to Dagger 2 with Android: Part 2, we add tests (with Espresso) to illustrate a common reason to use dependency injection.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Written by John Tucker

Broad infrastructure, development, and soft-skill background

Responses (10)

What are your thoughts?