SoFunction
Updated on 2025-04-14

How to use dagger in kotlin's Android project

Use in Kotlin's Android project​Dagger​(especially​Dagger Hilt​​, the official recommended simplified version) for dependency injection (DI) can greatly improve the testability and modularity of the code.

1. Configure Dagger Hilt​​

​​1.1 Add dependencies

exist(Module) in:

plugins {
    id("") version "2.48" apply false
}
dependencies {
    implementation(":hilt-android:2.48")
    kapt(":hilt-compiler:2.48") // Kotlin annotation processor}

exist(Project) in:

plugins {
    id("") version "2.48" apply false
}

​​1.2 Enable Hilt​​

existApplicationAdded on the class@HiltAndroidApp

@HiltAndroidApp
class MyApp : Application()

​​2. Core annotations and usage ​​​

2.1 Injecting dependencies to Android classes

use@InjectTag the dependencies that need to be injected and in the target class (such asActivityFragment) Added on@AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var myDependency: MyDependency // Dependency injection    override fun onCreate(savedInstanceState: Bundle?) {
        (savedInstanceState)
        () // Use directly    }
}

​​2.2 Provide dependencies (Module)​​

use@Moduleand@ProvidesDefinition dependencies:

@Module
@InstallIn(SingletonComponent::class) // Scope is global singletonobject AppModule {
    @Provides
    fun provideMyDependency(): MyDependency = MyDependencyImpl()
}

​​2.3 Scoping

  • @Singleton: Global singleton (the entire application life cycle).
  • @ActivityScoped: Bind to the Activity life cycle.
  • @ViewModelScoped: Bind to the ViewModel lifecycle.
@Module
@InstallIn(ViewModelComponent::class) // Scope is ViewModelobject ViewModelModule {
    @ViewModelScoped
    @Provides
    fun provideMyViewModelDependency(): MyViewModelDependency = MyViewModelDependencyImpl()
}

​​3. Inject ViewModel​​

CombinedViewModelandHilt

@HiltViewModel
class MyViewModel @Inject constructor(
    private val myDependency: MyDependency
) : ViewModel() {
    fun doWork() {
        ()
    }
}

existActivity/FragmentGet it in:

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    private val viewModel: MyViewModel by viewModels()
}

​​4. Inject interface or third-party library

4.1 Interface binding (@Binds)​​

interface MyRepository {
    fun getData(): String
}
class MyRepositoryImpl @Inject constructor() : MyRepository {
    override fun getData() = "Data from Repository"
}
@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
    @Binds
    abstract fun bindMyRepository(impl: MyRepositoryImpl): MyRepository
}

​​4.2 Inject Retrofit/ Room​​

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    fun provideRetrofit(): Retrofit {
        return ()
            .baseUrl("/")
            .addConverterFactory(())
            .build()
    }
    @Provides
    fun provideApiService(retrofit: Retrofit): ApiService {
        return (ApiService::)
    }
}

​​5. Frequently Asked Questions and Solutions

​​​​5.1 Compilation error: Cannot be provided without an @Provides

  • Cause​: Dagger cannot find a way to provide dependencies.
  • ​Solution​:
    • Check if it is correctly defined@Moduleand@Provides
    • make sure@InjectThe class can be constructed by Dagger (such as non-interface, non-third-party library classes).

​​5.2 Scope conflict

  • Error Example​: InActivityInjection@SingletonDependency, but the dependency requires@ActivityScoped
  • ​Solution​: Adjustment@InstallInand scope annotations to ensure life cycle matching.

​​5.3 Lazy injection

If the dependency initialization takes time, you can useLazy<T>

@Inject lateinit var heavyDependency: Lazy&lt;HeavyDependency&gt;
fun useDependency() {
    ().doWork() // Initialize when used}

​​6. Dagger Hilt vs. Dagger 2​​

Features ​Dagger Hilt​ ​Dagger 2​
​Configuration complexity Low (automatically generated components) High (requires manual definition of components)
Scope Management Built-in Android lifecycle scope (e.g.@ActivityScoped Need to customize the scope
Applicable scenarios Standard Android Projects Complex projects that require highly customization

​​7. Best Practices

  • ​​​​​Avoid global overuse@Singleton​​, select scope as needed. ​​
  • use@BindsReplacement@ProvidesInject interfaces to reduce template code.
  • Use in conjunction with ViewModel to avoid memory leaks.

This is the end of this article about using dagger in kotlin's Android project. For more related content on using dagger in kotlin, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!