一文带你了解 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 包体积优化实践------入门级攻略
相关推荐
彭波39636 分钟前
安卓手机端安装xapk、apkm软件!怎样安装xapk软件?安卓的apk和XAPK的区别?附教程
android·智能手机
Yang-Never1 小时前
ADB ->adb shell perfetto 抓取 trace 指令
android·开发语言·adb·android studio
2501_937189234 小时前
莫凡电视:地方台专属聚合 稳定直播播放工具
android·源码·源代码管理
耶叶5 小时前
Android 新权限申请模型(Activity Result API)
android
阿拉斯攀登5 小时前
【RK3576 安卓 JNI/NDK 系列 04】JNI 核心语法(下):字符串、数组与对象操作
android·驱动开发·rk3568·瑞芯微·rk安卓驱动·jni字符串操作
2501_915909065 小时前
不用越狱就看不到 iOS App 内部文件?使用 Keymob 查看和导出应用数据目录
android·ios·小程序·https·uni-app·iphone·webview
llxxyy卢6 小时前
web部分中等题目
android·前端
轩情吖6 小时前
MySQL之事务管理
android·后端·mysql·adb·事务·隔离性·原子性
万物得其道者成6 小时前
uni-app Android 离线打包:多环境(prod/dev)配置
android·opencv·uni-app
符哥20086 小时前
Firebase 官方提供的Quick Start-Android 库的功能集讲解
android