在kotlin的安卓项目中使用dagger

在 Kotlin 的 Android 项目中使用 ​​Dagger​ ​(特别是 ​​Dagger Hilt​​,官方推荐的简化版)进行依赖注入(DI)可以大幅提升代码的可测试性和模块化程度。

1. 配置 Dagger Hilt​

​1.1 添加依赖​

build.gradle (Module) 中:

Kotlin 复制代码
plugins {
    id("com.google.dagger.hilt.android") version "2.48" apply false
}

dependencies {
    implementation("com.google.dagger:hilt-android:2.48")
    kapt("com.google.dagger:hilt-compiler:2.48") // Kotlin 注解处理器
}

build.gradle (Project) 中:

Kotlin 复制代码
plugins {
    id("com.google.dagger.hilt.android") version "2.48" apply false
}

​1.2 启用 Hilt​

Application 类上添加 @HiltAndroidApp

Kotlin 复制代码
@HiltAndroidApp
class MyApp : Application()

​2. 核心注解与用法​

​2.1 注入依赖到 Android 类​

使用 @Inject 标记需要注入的依赖,并在目标类(如 ActivityFragment)上添加 @AndroidEntryPoint

Kotlin 复制代码
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var myDependency: MyDependency // 依赖注入

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        myDependency.doSomething() // 直接使用
    }
}

​2.2 提供依赖(Module)​

使用 @Module@Provides 定义依赖:

Kotlin 复制代码
@Module
@InstallIn(SingletonComponent::class) // 作用域为全局单例
object AppModule {
    @Provides
    fun provideMyDependency(): MyDependency = MyDependencyImpl()
}

​2.3 作用域(Scoping)​

  • @Singleton:全局单例(整个应用生命周期)。
  • @ActivityScoped:与 Activity 生命周期绑定。
  • @ViewModelScoped:与 ViewModel 生命周期绑定。
Kotlin 复制代码
@Module
@InstallIn(ViewModelComponent::class) // 作用域为 ViewModel
object ViewModelModule {
    @ViewModelScoped
    @Provides
    fun provideMyViewModelDependency(): MyViewModelDependency = MyViewModelDependencyImpl()
}

​3. 注入 ViewModel​

结合 ViewModelHilt

Kotlin 复制代码
@HiltViewModel
class MyViewModel @Inject constructor(
    private val myDependency: MyDependency
) : ViewModel() {
    fun doWork() {
        myDependency.doSomething()
    }
}

Activity/Fragment 中获取:

Kotlin 复制代码
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    private val viewModel: MyViewModel by viewModels()
}

​4. 注入接口或第三方库​

​4.1 接口绑定(@Binds)​

Kotlin 复制代码
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 注入 Retrofit / Room​

Kotlin 复制代码
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

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

​5. 常见问题与解决​

​5.1 编译错误:Cannot be provided without an @Provides

  • ​原因​:Dagger 找不到依赖的提供方式。
  • ​解决​
    • 检查是否正确定义了 @Module@Provides
    • 确保 @Inject 的类可以被 Dagger 构造(如非接口、非第三方库类)。

​5.2 作用域冲突​

  • ​错误示例​ :在 Activity 中注入 @Singleton 依赖,但该依赖需要 @ActivityScoped
  • ​解决​ :调整 @InstallIn 和作用域注解,确保生命周期匹配。

​5.3 延迟注入(Lazy)​

如果依赖初始化耗时,可以使用 Lazy<T>

Kotlin 复制代码
@Inject lateinit var heavyDependency: Lazy<HeavyDependency>

fun useDependency() {
    heavyDependency.get().doWork() // 使用时才初始化
}

​6. Dagger Hilt vs. Dagger 2​

​特性​ ​Dagger Hilt​ ​Dagger 2​
​配置复杂度​ 低(自动生成组件) 高(需手动定义组件)
​作用域管理​ 内置 Android 生命周期作用域(如 @ActivityScoped 需自定义作用域
​适用场景​ 标准 Android 项目 需要高度定制的复杂项目

​7. 最佳实践​

  1. ​避免全局过度使用 @Singleton,按需选择作用域。
  2. ​用 @Binds 替代 @Provides 注入接口,减少模板代码。
  3. ​结合 ViewModel 使用​,避免内存泄漏。
Kotlin 复制代码
class DeviceManager @Inject constructor(
    private val aService: IAService,
    private val bService: IBService
) {

@Inject 注解的作用 这里的 @Inject constructor() 表示该构造函数由依赖注入框架(如 Dagger/Hilt)管理,框架会自动创建 DeviceCmdManager 实例,并注入其依赖项 bleService 和 mqttService。

Kotlin 复制代码
依赖注入框架会根据类型(IAService/IBService)自动寻找对应的实现类,开发者无需手动实例化这些服务对象。
使用场景示例 当其他类需要 DeviceManager 时,只需声明依赖即可自动获取实例
 class SomeViewModel @Inject constructor(
       private val manager: DeviceManager // 自动注入
   )
相关推荐
翻滚丷大头鱼1 年前
Android hilt使用
android·hilt·dagger2