Welcome to Android Hilt Tutorial. I hope you all are aware of Dependency Injection. While building an application (or android application) we use a lot of dependencies. Now you can manage all the dependencies yourself (And you may already managing it if you aren’t using Dependency Injection).
But using Dependency Injection Pattern has many benefits and it is recommended that you should use Dependency Injection in your project. And to use this pattern, we have many libraries that simplifies our Task. One of the most popular solution for Dependency Injection that we use is Dagger. But using Dagger is very complicated and it has a steep learning curve. And with dagger there is a lot of boilerplate code has to be written.
Considering these problems a new solution is released by Android Team, that is called Hilt. It is a new library built on the top of Dagger. The goals of Android Hilt are:
- Simplify Dagger Implementation in Android Project
- Create a standard set of components and scopes so that it is easy to setup.
In this post, we will learn using Android Hilt for injecting dependencies. And trust me using Hilt is very very easy.
For this post I will be using an old project, and before moving ahead you should get the code from here.
Table of Contents
Android Hilt Tutorial – Video
If you are more comfortable in watching a video that explains about using Hilt, the you should watch this video tutorial.
Android Hilt Tutorial
But if you want to read the post, then let’s move ahead. We will start by adding Hilt Dependencies.
Adding Hilt Dependencies
- First open your project level build.gradle file and add this classpath inside dependencies block.
1 2 3 |
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.35' |
- Now go to app level build.gradle file and add the following plugin.
1 2 3 |
id "dagger.hilt.android.plugin" |
- Finally add these two lines inside app level build.gradle file’s dependencies block.
1 2 3 4 |
implementation "com.google.dagger:hilt-android:2.35" kapt "com.google.dagger:hilt-compiler:2.35" |
- Now sync your project and you’re done.
Injecting a Dependency
For the sake of example, you can consider the following class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class AuthRepository @Inject constructor( private val api: AuthApi, private val preferences: UserPreferences ) : BaseRepository(api) { suspend fun login( email: String, password: String ) = safeApiCall { api.login(email, password) } suspend fun saveAccessTokens(accessToken: String, refreshToken: String) { preferences.saveAccessTokens(accessToken, refreshToken) } } |
Here you can see I have added @Inject annotation to the class constructor. By adding this annotation I am telling hilt that you have to give AuthRepository whenever it is requested.
But the problem here is, Hilt do not know how to construct the dependencies that are required to build AuthRepository. In this example AuthRepository requires AuthApi and UserPreferences.
And that is why we also need to add @Inject to dependent classes as well. But we cannot always construct inject, there are situations when it is not possible. For example in the above code AuthApi is an interface and we cannot construct inject it. And also if there are some classes that we do not own for example Retrofit then also it is not possible to constructor inject it.
For these situations, we need to tell hilt that how these dependencies can be created. And to tell hilt this thing, we can create a module.
Creating a Module
Create an object named AppModule .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Module @InstallIn(SingletonComponent::class) object AppModule { @Provides fun provideAuthApi( remoteDataSource: RemoteDataSource, @ApplicationContext context: Context ): AuthApi { return remoteDataSource.buildApi(AuthApi::class.java, context) } } |
It is a standard dagger module only, but we have a new annotation @InstallIn here. With hilt we do not need to create a component. Hilt will create the component automatically and that is why while creating a module, we need to tell hilt that where this module should be installed. So in the above code I am telling hilt that this module is for SingletonComponent . And SingletonComponent is the top most class of Component Hierarchy, as you can see in the below image.
So if you want something everywhere, you can use SingletonComponent , and you can use other classes as per your requirement.
Injecting inside a Fragment
Now we can simply Inject the repository inside our Fragment.
1 2 3 4 5 6 7 8 |
@AndroidEntryPoint class LoginFragment : Fragment(R.layout.fragment_login) { @Inject lateinit var repository: AuthRepository . . |
Note that, I’ve also added @AndroidEntryPoint annotation. Hilt will only provide dependencies to the classes annotated with @AndroidEntryPoint .
And currently hilt supports the following android classes.
- Application
- ViewModel
- Activity
- Fragment
- View
- Service
- BroadcastReceiver
Please not that in the above example, you also need to add @AndroidEntryPoint annotation to the host Activity of the fragment.
Creating a ViewModel
Hilt supports ViewModel, and that is why working with ViewModels, are very easy with hilt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@HiltViewModel class AuthViewModel @Inject constructor( private val repository: AuthRepository ) : BaseViewModel(repository) { private val _loginResponse: MutableLiveData<Resource<LoginResponse>> = MutableLiveData() val loginResponse: LiveData<Resource<LoginResponse>> get() = _loginResponse fun login( email: String, password: String ) = viewModelScope.launch { _loginResponse.value = Resource.Loading _loginResponse.value = repository.login(email, password) } suspend fun saveAccessTokens(accessToken: String, refreshToken: String) { repository.saveAccessTokens(accessToken, refreshToken) } } |
Just annotate your ViewModels with @HiltViewModel , and that’s it.
Requesting a ViewModel
Remember that you cannot simply request a ViewModel. As we construct ViewModel using the ViewModelProvider API. To request a ViewModel inside your fragment/activity use the following code.
1 2 3 |
private val viewModel: AuthViewModel by viewModels() |
And that’s it.
Android Hilt Tutorial – Source Code
If you want to get the full working code of the project then you can get it from here.
So that’s all for this Android Hilt Tutorial friends. In case you have any problem, confusion or question just leave it below in the comments section. Thank You.