HILT ANDROID
What is Hilt in Android?
Hilt is a modern, fully integrated dependency injection (DI) library for Android applications, built on top of Dagger, one of the most popular DI frameworks for Java and Android. Hilt simplifies the setup and usage of dependency injection, providing a standard way of managing dependencies in your Android apps.
If you're familiar with dependency injection, you know that it allows you to pass dependencies to objects at runtime instead of having to create them manually. This promotes loose coupling, testability, and modularity in your code.
Hilt integrates well with the Android lifecycle, making it easier to manage dependencies in components such as Activities, Fragments, ViewModels, and Services.
Table of Contents
- What is Dependency Injection?
- Why Use Hilt in Android?
- How to Set Up Hilt in an Android Project
- Basic Concepts of Hilt
- Using Hilt for Dependency Injection
- Scopes and Modules in Hilt
- ViewModel Integration with Hilt
- Testing with Hilt
- Conclusion
1. What is Dependency Injection?
Dependency Injection (DI) is a design pattern where an object’s dependencies (services, data, etc.) are provided by an external source, rather than the object itself creating or managing them. This pattern reduces the need for tight coupling between classes, making code more flexible, modular, and easier to test.
For example, in an Android app, instead of creating an instance of a repository class inside your ViewModel, you inject the repository into the ViewModel. This allows you to easily swap out the repository for testing or for different implementations (such as a mock repository or a real one).
Benefits of Dependency Injection:
- Testability: Easier to write unit tests by injecting mock dependencies.
- Separation of Concerns: It separates the creation of an object from its usage.
- Decoupling: Components become independent of each other, making them more flexible.
2. Why Use Hilt in Android?
Hilt was created to simplify the usage of Dagger in Android projects. Dagger, while powerful, can sometimes feel verbose and requires a lot of boilerplate code. Hilt reduces this complexity and provides out-of-the-box support for Android components like Activities, Fragments, and ViewModels.
Key Benefits of Hilt:
- Simplified setup: Hilt removes much of the boilerplate code that comes with using Dagger manually.
- Integration with Android's lifecycle: Hilt provides built-in scopes for Android components such as
@ActivityScoped,@FragmentScoped, and@ViewModelScoped. - Code generation: Hilt generates necessary code under the hood, making it easier to use DI in Android without worrying about low-level configuration.
- Better testing: Hilt makes it easy to provide mock dependencies in your tests.
3. How to Set Up Hilt in an Android Project
To start using Hilt in an Android project, follow these steps:
Step 1: Add Dependencies
Open your build.gradle file and add the following dependencies for Hilt:
// In your project's build.gradle file (root)
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.41"
}
}
// In your app module's build.gradle file
apply plugin: 'dagger.hilt.android.plugin'
dependencies {
// Hilt dependencies
implementation "com.google.dagger:hilt-android:2.41"
kapt "com.google.dagger:hilt-compiler:2.41" // For annotation processing
}
Step 2: Enable Kotlin KAPT (if using Kotlin)
If you are using Kotlin, add the kapt plugin to your build.gradle file:
apply plugin: 'kotlin-kapt'
Step 3: Initialize Hilt in the Application Class
Create or modify your Application class to use Hilt:
import android.app.Application;
import dagger.hilt.android.HiltAndroidApp;
@HiltAndroidApp // Marks this class for Hilt
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Application setup
}
}
Don't forget to specify your Application class in the AndroidManifest.xml:
<application
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.MyApplication">
<!-- Other manifest configurations -->
</application>
4. Basic Concepts of Hilt
Hilt introduces several important annotations and concepts that simplify dependency injection:
- @HiltAndroidApp: Marks the
Applicationclass to trigger Hilt's code generation and setup. - @Inject: Marks the constructor of a class where dependencies will be provided.
- @Module: A class that provides dependencies. You define how to create objects and annotate methods with
@Provides. - @InstallIn: Specifies which Hilt component the module should be installed in (e.g.,
@InstallIn(ApplicationComponent.class)). - @Component: Hilt uses predefined components (like
ApplicationComponent,ActivityComponent, etc.) to manage the scopes of the dependencies.
5. Using Hilt for Dependency Injection
Injecting Dependencies into Android Components (Activities, Fragments)
You can inject dependencies directly into Android components such as Activity, Fragment, and Service.
Example:
- Create a Service Class:
import javax.inject.Inject;
public class MyRepository {
@Inject
public MyRepository() {
// Constructor logic
}
public String fetchData() {
return "Hello from Repository!";
}
}
- Inject in an Activity:
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import dagger.hilt.android.AndroidEntryPoint;
import javax.inject.Inject;
@AndroidEntryPoint // Hilt will handle dependency injection for this Activity
public class MainActivity extends AppCompatActivity {
@Inject // Hilt will provide this dependency
MyRepository myRepository;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.textView);
textView.setText(myRepository.fetchData());
}
}
In this example:
- @AndroidEntryPoint tells Hilt to inject dependencies into this
Activity. - @Inject tells Hilt to provide an instance of
MyRepository.
6. Scopes and Modules in Hilt
In Hilt, scopes define the lifetime of dependencies. You can scope dependencies to Android components (like Activity, Fragment, etc.) to ensure they live as long as their corresponding component.
Example of creating a module to provide dependencies:
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;
@Module
@InstallIn(SingletonComponent.class) // Makes this module available in the app-wide scope
public class AppModule {
@Provides
public static MyRepository provideRepository() {
return new MyRepository();
}
}
- @Singleton: Ensures the same instance of the dependency is used throughout the application.
- @ActivityScoped: Ensures the dependency is created and used only within the lifespan of an activity.
7. ViewModel Integration with Hilt
Hilt simplifies the injection of dependencies into ViewModels. You can use @HiltViewModel to tell Hilt to inject dependencies into your ViewModel.
Example:
- Create a ViewModel:
import androidx.hilt.lifecycle.ViewModelInject;
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
private final MyRepository myRepository;
@ViewModelInject // Tells Hilt to provide the dependency
public MyViewModel(MyRepository myRepository) {
this.myRepository = myRepository;
}
public String fetchData() {
return myRepository.fetchData();
}
}
- Inject ViewModel into Activity:
import androidx.activity.viewModels;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
private final MyViewModel viewModel by viewModels();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.textView);
textView.setText(viewModel.fetchData());
}
}
8. Testing with Hilt
Testing with Hilt is easy. You can use Hilt in your test classes to inject mock dependencies.
Example:
import androidx.test.ext.junit.runners.AndroidJUnit4;
import dagger.hilt.android.testing.HiltAndroidRule;
import dagger.hilt.android.testing.HiltAndroidTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@HiltAndroidTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
@Rule
public HiltAndroidRule hiltRule = new HiltAndroidRule(this);
@Test
public void testRepositoryInjection() {
// Test your injected dependencies here
}
}
9. Conclusion
Hilt makes dependency injection in Android simple, efficient, and aligned with Android's lifecycle. It reduces the boilerplate and complexity that comes with using traditional DI frameworks like Dagger. By using Hilt, developers can manage dependencies with less code and fewer errors, allowing them to focus more on business logic and app functionality.
Hilt integrates seamlessly with Android components like Activities, Fragments, and ViewModels, and it also provides an easy testing setup. With its powerful features and ease of use, Hilt is a great tool for building scalable and maintainable Android applications.

0 Comments