Hilt

Hilt is a dependency injection library for Android that reduces the boilerplate of Dagger by providing a standard way to incorporate dependency injection into an Android application. Hilt is built on top of Dagger, simplifying its setup and usage while integrating seamlessly with Android components like Activities, Fragments, and Services.

Key Concepts of Hilt

  1. Hilt Modules: Provide dependencies and are annotated with @Module and @InstallIn.

  2. Entry Points: Android components like Activities, Fragments, and Services that can receive dependencies, annotated with @AndroidEntryPoint.

  3. Scopes: Manage the lifecycle of dependencies with predefined scopes like @Singleton, @ActivityScoped, etc.

  4. Hilt Components: Automatically generated components for different Android classes like ApplicationComponent, ActivityComponent, etc.

Setting Up Hilt in an Android Kotlin Project

  1. Add Hilt Dependencies: Update your build.gradle or build.gradle.kts files to include Hilt dependencies.

// Root level project
plugins {
    id("com.google.dagger.hilt.android") version "latest-version" apply false
}

// App level 
plugins {
    id("kotlin-kapt")
    id("dagger.hilt.android.plugin")
}

dependencies {
    implementation("com.google.dagger:hilt-android:latest_version")
    implementation("com.google.dagger:hilt-compiler:latest_version")
    kapt("com.google.dagger:hilt-android-compiler:latest_version")
    
    // using jetpack compose add this
    implementation("androidx.hilt:hilt-navigation-compose:latest_version")
}
  1. Annotate the Application Class: Use @HiltAndroidApp to enable Hilt in your application.

@HiltAndroidApp
class App : Application() {
}
  1. Create Hilt Modules: Define modules to provide dependencies.

You can use extension functions to inject retrofits from onelib's built-in functions. For example

import com.wahidabd.library.data.libs.ApiService
import com.wahidabd.library.data.libs.OkHttpClientFactory
import com.wahidabd.library.utils.coroutine.handler.ErrorParser

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Singleton
    @Provides
    fun provideOkhttpClient(): OkHttpClient = OkHttpClientFactory.create(
        interceptors = listOf(),
        authenticator = null,
        certificatePinner = null,
        showDebugLog = BuildConfig.DEBUG
    )

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit =
        ApiService.createService(okHttpClient, "your_base_url")

    @Singleton
    @Provides
    fun provideErrorParser(retrofit: Retrofit): ErrorParser = ErrorParser(retrofit)
    
    // inject data layer and domain layer
    @Provides
    @Singleton
    fun provideYourService(retrofit: Retrofit): YourService =
        retrofit.create(YourService::class.java)

    @Singleton
    @Provides
    fun provideYourDataStore(
        api: YourService,
        error: ErrorParser
    ): MangaRepository = YourDataStore(api, error)

    @Singleton
    @Provides
    fun provideYourInteractor(repository: YourRepository): YourUseCase =
        YourInteractor(repository)
}
  1. Inject Dependencies in a ViewModel

@HiltViewModel
class YourViewModel @Inject constructor(
    private val useCase: YourUseCase
) : ViewModel(){}
  1. Inject Dependencies in Android Components: Use @AndroidEntryPoint on Activities, Fragments, Services, etc., and @Inject to request dependencies.

@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding>() {

    private val viewModel: yourViewModel by viewModels()

    override fun initIntent() {}
    override fun initUI() {}
    override fun initAction() {}
    override fun initProcess() {}
    override fun initObservers() {}
}

if you are using jetpack compose and want to inject into a composable function

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourAppTheme() {
                YourComposabelFunction()
            }
        }
    }
}

@Composable
fun YourComposabelFunction(
    private val viewModel: YourViewModel = hiltViewModel()
){
    // content
}

Hilt simplifies dependency injection in Android development using Kotlin by providing a clear structure for managing dependencies, integrating seamlessly with Android components, and reducing boilerplate code. By leveraging Hilt, developers can create more modular, maintainable, and testable applications.

Last updated