Dependency injection in Android using Hilt
Let’s first break the term to understand what is Dependency Injection
Dependency
Say we have a Car class:
Here our class Car needs the object of the Engine and Wheel class to work.
When a class is dependent on other classes ( Car class needs Engine class and Wheel class), the required classes are called dependencies.
Why dependency is a problem?
Every time we need a Car object, we have to create an Engine and Wheel class too. For a small project it wouldn’t matter, but as the number of required Car objects increases, you would have to create the same amount of Engine and Wheel objects too. So, say for 1000 Car objects you would have to create 1000 Engine and Wheel objects too.
Injection
To solve this problem, we use a library — Hilt. What this does is, it injects (or provides ) the other required class objects, Engine and Wheel in our case, to our Car class.
Advantages of implementing dependency injection:
- Re-usability of code
- Ease of refactoring
- Ease of testing
What is Hilt?
Hilt is a dependency injection library for Android that reduces the boilerplate of doing manual dependency injection in your project. Doing manual dependency injection requires you to construct every class and its dependencies by hand, and to use containers to reuse and manage dependencies.
Understanding how to use Hilt in a demo project
Step 1: Adding dependencies
First, add the hilt-android-gradle-plugin plugin to your project’s root build.gradle file:
Then, apply the Gradle plugin and add these dependencies in your app/build.gradle file:
( Hilt uses Java 8 features. To enable Java 8 in your project, add the following to compileOptions )
Step 2: Creating Application class
All apps that use Hilt must contain an Application class that is annotated with @HiltAndroidApp. The @HiltAndroidApp annotation makes this class a container for all the dependencies of our application.
Let’s create our Application class:
Step 3: Creating Car (dependency) class
The @Inject annotation helps in passing the dependency required by MainActivity.kt which is stored in the container (i.e. BaseApplication for us)
Step 4: Using the dependency in MainActivity.kt
Did you notice that we did not manually create the car object ( car = Car() ) ?
The @Inject annotation helps in passing the dependency required by MainActivity.kt which is stored in the container (i.e. BaseApplication for us)
The @AndroidEntryPoint annotation allows the class to use every dependency stored in the container (i.e. BaseApplication for us)
The @Inject annotation helps passing the dependency class, had it not been this, we have to manually create object (i.e. car=Car())
Running the App we get this message in Logcat:
car: Car is running
What is Field Injection?
Certain Android framework classes such as activities and fragments are instantiated by the system. In this case, we use field injection, where dependencies are instantiated after the class is created.
Is there any other type?
Yes, Constructor Injection, where you pass the dependencies of a class to its constructor.
To understand Constructor Injection let’s modify our code a bit.
Let’s create 2 other classes, Engine and Wheel that would be required by the Car
- Wheel.kt
- Engine.kt
If you forgot, the @Inject annotation helps in passing the dependency classes.
Now, let’s modify our Car.kt class so it uses Engine and Wheel.
Now we use the dependency in MainActivity.kt
Here, we did not have to pass any arguments ( Engine and Wheel object ) to the Car class object. This is known as constructor injection
Running the App we get this message in Logcat:
engine: Engine started
wheel: Wheel is rotating
car: Car is running
Start using Hilt
If you’re intrigued by Hilt and want to learn more about it, here’s some resources for you to learn:
Documentation: [Click here]
Sample project: [Github link]
Codelabs: [Click here]
HILT Cheatsheet: [Click here]
For more updates, follow: @shashi-kant10
Article by : Shashi Kant