Hilt: Simplifying Dependency Injection in Android

Mukesh RajputMukesh Rajput
2 min read

Dependency injection (DI) offers a structured approach to provide objects to classes without directly creating them. Hilt, an extension library built on top of Dagger, streamlines DI by automating boilerplate code and integrating seamlessly with Jetpack libraries like ViewModels.

Integration Steps:

Add Hilt to your Gradle dependencies:

implementation "com.google.dagger:hilt-android:$hiltVersion"
kapt "com.google.dagger:hilt-compiler:$hiltVersion"

Replace $hiltVersion with the latest Hilt version.

Create a Application Class:

Extend Application and annotate it with @HiltAndroidApp. This triggers Hilt's code generation for dependency injection.

@HiltAndroidApp
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // Optional: Initialize other application-wide dependencies here
    }
}

Using Hilt with ViewModels:

  1. Create a ViewModel Module: Annotate a class with @Module and @InstallIn(SingletonComponent::class).
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient {
        // ... Configure OkHttpClient instance
    }

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        // ... Configure Retrofit instance using OkHttpClient
    }

    @Provides
    @Singleton
    fun provideApiService(retrofit: Retrofit): MyApiService {
        return retrofit.create(MyApiService::class.java)
    }
}

There are a few types of scoping available in Hilt:

2. Inject Dependencies into Your ViewModel: Annotate your ViewModel class with @HiltViewModel. Mark the constructor with @Inject and include any dependencies you need.

@HiltViewModel
class MyViewModel @Inject constructor(private val apiService: MyApiService) : ViewModel() {

    fun fetchData() {
        viewModelScope.launch {
            val data = apiService.getData()
            // Update UI or perform other actions with the data
        }
    }
}

3. Obtain the ViewModel in an Activity or Fragment:

class MyActivity : AppCompatActivity() {

    private val viewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

Benefits of Using Hilt:

  • Reduced boilerplate code: Hilt automates dependency creation and injection, allowing you to focus on core app logic.

  • Improved testability: Classes become less coupled to concrete implementations, making them easier to test in isolation.

  • Clearer code organization: Modules encapsulate dependency creation logic, promoting better maintainability.

By effectively leveraging Hilt, you can enhance the structure and maintainability of your Android projects, making them more efficient and testable.

0
Subscribe to my newsletter

Read articles from Mukesh Rajput directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mukesh Rajput
Mukesh Rajput

Specializing in creating scalable and maintainable applications using MVVM and Clean Architecture principles. With expertise in Ktor, Retrofit, RxJava, View Binding, Data Binding, Hilt, Koin, Coroutines, Room, Realm, and Firebase, I am committed to delivering high-quality mobile solutions that provide seamless user experiences. I thrive on new challenges and am constantly seeking opportunities to innovate in the Android development space.