一文带你了解 Android 中 Dagger/Hilt 的原理和简单使用

一、依赖注入(DI)与框架概述

依赖注入 是一种设计模式,通过将对象的创建和依赖关系从代码中解耦,提升代码的可测试性、可维护性和可扩展性。在 Android 开发中,DaggerHilt 是主流的 DI 框架:

  • Dagger:基于 Java 注解处理器(APT)的编译时 DI 框架,生成高效代码,但配置复杂。
  • Hilt:基于 Dagger 的 Android 专用框架,简化配置并与 Android 组件深度集成。

二、Dagger/Hilt 实现原理

1、Dagger 核心原理

  • 注解处理器 :在编译时解析 @Component@Module 等注解,生成 DaggerXxxComponent 类。
  • 组件(Component):作为依赖注入的容器,连接模块(Module)和注入目标。
  • 依赖图:构建对象依赖关系图,确保依赖按需创建并正确传递。

2、Hilt 的优化

  • 预定义组件 :自动为 ActivityFragmentViewModel 等生成组件,无需手动声明。
  • 内置绑定 :通过 @AndroidEntryPoint 注解自动注入 Android 框架类(如 Application)。
  • 简化作用域 :通过 @Singleton@ActivityScoped 等注解管理生命周期。

三、Hilt 使用示例

1、项目配置(Gradle)

gradle 复制代码
// 根 build.gradle
dependencies {
    classpath 'com.google.dagger:hilt-android-gradle-plugin:2.48'
}

// app/build.gradle
plugins {
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

dependencies {
    implementation 'com.google.dagger:hilt-android:2.48'
    kapt 'com.google.dagger:hilt-android-compiler:2.48'
    // 可选:Hilt 和 ViewModel 集成
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
    kapt 'androidx.hilt:hilt-compiler:1.0.0'
}

2、初始化 Hilt

kotlin 复制代码
// Application 类
@HiltAndroidApp
class MyApp : Application()

3、定义依赖模块

kotlin 复制代码
@Module
@InstallIn(SingletonComponent::class) // 模块作用域为全局单例
object AppModule {
    @Provides
    @Singleton
    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)
    }
}

4、注入依赖到 Activity

kotlin 复制代码
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var apiService: ApiService // 自动注入

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

5、ViewModel 注入

kotlin 复制代码
@HiltViewModel
class UserViewModel @Inject constructor(
    private val userRepository: UserRepository
) : ViewModel() {
    fun loadUser() = userRepository.getUser()
}

四、使用场景与优势

1、适用场景

  • 复杂依赖管理 :多层依赖(如 ViewModelRepositoryDataSource)。
  • 全局单例:网络客户端(Retrofit)、数据库(Room)、SharedPreferences。
  • 测试替代:通过替换 Module 提供 Mock 对象进行单元测试。
  • 多环境配置:根据 Build 类型切换 API 地址或数据源。

2、Hilt 的核心优势

  • 简化配置:自动生成组件,减少模板代码。
  • 生命周期感知:自动处理 Android 组件的生命周期绑定。
  • 与 Jetpack 集成:支持 ViewModel、WorkManager 等组件。

五、Dagger vs Hilt 对比

特性 Dagger Hilt
配置复杂度 高(需手动定义组件和子组件) 低(预定义组件,自动注入)
Android 集成 需要自行绑定生命周期 深度集成,支持 @AndroidEntryPoint
代码生成 显式生成 DaggerComponent 隐式生成,更简洁
适用项目 超大型项目,需要高度自定义 中小型项目,快速开发

六、常见问题与解决

1、编译错误:找不到绑定

  • 原因:未提供依赖或 Module 未正确安装。
  • 解决 :检查 @Provides 方法或添加 @Inject 构造函数。

2、作用域冲突

  • 现象:同一作用域内多次创建实例。
  • 解决 :使用 @Singleton 或自定义作用域注解。

3、循环依赖

  • 示例:A 依赖 B,B 又依赖 A。
  • 解决 :重构代码,或使用 @Lazy 延迟注入。

七、总结

  • Hilt 是 Android DI 的未来:Google 官方推荐,适合大多数项目。

  • 最佳实践

    • 使用 @HiltViewModel 注入 ViewModel。
    • 通过 @InstallIn 控制模块作用域。
    • 优先使用构造函数注入(@Inject constructor)。
  • 性能优化:合理使用作用域,避免全局单例滥用。

更多分享

  1. Android 应用【内存优化】指南
  2. Android 应用【内存泄漏】优化指南
  3. Android ContentProvider 详解及结合 Jetpack Startup 的优化实践
  4. Android 冷启动优化实践:含主线程优化、资源预加载与懒加载、跨进程预热等
  5. Android RecyclerView 性能优化指南
  6. Android 包体积优化实践------入门级攻略
相关推荐
奔跑吧 android1 小时前
【android bluetooth 协议分析 12】【A2DP详解 1】【车机侧蓝牙音乐免切源介绍】
android·bluetooth·bt·gd·a2dpsink·免切源·aosp14
struggle20252 小时前
适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO
yolo·ios·开源·app·swift
飞猿_SIR2 小时前
Android Exoplayer多路不同时长音视频混合播放
android·音视频
前端懒猫2 小时前
android实现USB通讯
android
jiet_h3 小时前
Android锁
android
teacher伟大光荣且正确11 小时前
Qt Creator 配置 Android 编译环境
android·开发语言·qt
飞猿_SIR14 小时前
Android Exoplayer 实现多个音视频文件混合播放以及音轨切换
android·音视频
HumoChen9914 小时前
GZip+Base64压缩字符串在ios上解压报错问题解决(安卓、PC模拟器正常)
android·小程序·uniapp·base64·gzip
yxc_inspire18 小时前
基于Qt的app开发第七天
开发语言·c++·qt·app
沙振宇18 小时前
【HarmonyOS】ArkTS开发应用的横竖屏切换
android·华为·harmonyos