Dagger 2 for Android Beginners — Advanced part II

Hari Vignesh Jayapalan
5 min readDec 30, 2017

--

This story is the seventh part of the series, Dagger 2 for Android Beginners. If you did not read the previous one, you can start from below.

Series Pitstops

Previously on Dagger 2..

We took a sample kickstarter project and attempted to decouple and inject the dependencies using Dagger 2 APIs and annotations.

We also saw 3 new annotations. One is @Scope — which is used to get singleton dependencies. Next is @Named — which is used to differentiate dependency providers. Another one is the@Qualifier annotation, an alternate to @Named annotation and we saw the implementation of both.

Creating multiple Components

Till last pit stop, we created Application level dependencies. But what if we need some dependencies at the Activity level? Since Activity creates and destroys in its own lifecycle, how about its dependencies as well? So, dependencies created within Activity should be destroyed with Activity itself.

The best practice here is, when you’re injecting dependencies into clients who have different lifecycle from where dependencies are coming, it’s better to create a separate module and component for them.

In this example, I did not want to add additional features to explain this. Instead, let’s consider our MainActivity as a separate feature and let’s create separate module and component for it.

For the following changes, refer the branch Dagger2Part2

Step 1: Creating Activity level scope

For the upcoming changes, in the branch above, I have packaged all the new files under MainActivityFeature.

We have to create a new Scope for our MainActivity.

Step 2: Creating Component for MainActivity

Now, let’s create a separate Component for MainActivity with MainActivityScope.

As you notice in the gist, we need to make our MainActivityComponent talk to our RandomUserComponent. So, we’ve used the attribute dependencies to make it talk to it. In other words, it tells dagger that if you need additional dependencies for this component, look at RandomUserComponent.

For the Activity level, for our example, we need the adapter and the API call as the dependencies. Hence the methods getRandomUserAdapter() and getRandomUserService().

Step 3: Creating MainActivity Module

Let’s now create a module for MainActivity, which provides the adapter dependency.

Note: Injecting MainActivity through the adapter is not necessary. Just for the example, I’m doing it. If you need Context for Picasso, you can use holder.imageView.getContext().

Notice the scope @MainActivityScope that we’ve added to randomUserAdapter() method — to limit the scope within the Activity.

We also need to map this module to its corresponding Component MainActivityComponentmodules = MainActivityModule.class

Linked all Components and Modules

Step 4: Creating Application Class

This Application class holds all the application level dependencies — RandomUserApplicationComponent.

Step 5: Modifying MainActivity

If you would have hit the build button, Dagger would have created DaggerMainActivityComponent for us. Using this, in our MainActivity, we need to get Activity level dependencies — adapter and API service.

Note: In the branch, look for the method afterActivityLevelComponent()

Step 6: Congratulate yourself

Yes. we’ve somewhat established some manageable code. We have created activity level dependencies. Congratulate yourself :-)

What if we have 50 dependencies in our Component?

So, the question is what if if we have more dependencies? do we need to write same statements like below all the time?

randomUserApi = mainActivityComponent.getRandomUserService();
mAdapter = mainActivityComponent.getRandomUserAdapter();
….

You might think that you don’t care as well. But I know someone who can shorten it for you. Yes. it’s @Inject annotation!

Using @Inject annotation

Instead of telling Dagger that you want RandomUserService and RandomUserAdapter, let Dagger react upon the field with @Inject annotations.

By little modification as below, we’ll be able to use @Inject in no time. Please refer the following branch InjectMainActivity

Modifying MainActivityComponent

Remove the methods getRandomUserService() and getRandomUserAdapter() and add the method to inject MainActivity.

Modifying MainActivity

How does this work? well, when Dagger finds the void method — no return type, it knows that there must be something that it needs in the class i.e. the fields annotated @Inject and it will initialise them.

Yes! that’s it. Now you can run the code!

TL;DR

We saw an example on creating and injecting dependencies at the activity level. In other words, creating and interacting components when the client has its own lifecycle.

We also saw an example of using @Inject annotation to inject MainActivity.

Closing note

Thank you for taking your time to read and support the entire series. I hope you have at-least gained some insights about Dependencies and Dagger 2. The reason I wrote this series is that, I gained knowledge about Dagger 2 by reading many blogs but I gained even more insights when I explained it back to you (writing blogs). So I encourage all the readers to share the knowledge back in any way possible. I’m not an expert in Dagger 2, I consider myself a learner. So, if you have found any better way to explain this or any alternate approach, please do write a post and tag this series.

Feedback

If you have found any faults or if the explanation is not clear or a better approach, please write to me to hariutd@gmail.com.

I encourage feedback and it’s the quick way to learn and reiterate myself.

What’s Next?

Well, this is the last part of the series. If I come across other resources, I will definitely write about it.

You can now check other resources and I hope you will understand that content — as you would have gained the foundation in this series.

References and other resources

Happy Learning! Bye! See you soon :-)

Thank you for using your precious time to reading this article. Liked it? Clap your 👏 to say “thanks!” and help others find this article.

--

--

Hari Vignesh Jayapalan

Android Dev at WeTransfer| ex Backbase | #1 Google AAD | Public Speaker | Blogger | Creative Coder & Logical Designer