一文带你了解 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 包体积优化实践------入门级攻略
相关推荐
Tsing7224 分钟前
Android vulkan示例
android
每次的天空1 小时前
高性能 Android 自定义 View:数据渲染与事件分发的双重优化
android
KdanMin1 小时前
Android 13组合键截屏功能的彻底移除实战
android
_祝你今天愉快1 小时前
安卓源码学习之【导航方式切换分析及实战】
android·源码
&有梦想的咸鱼&1 小时前
Android Compose 框架物理动画之弹簧动画(Spring、SpringSpec)深入剖析(二十七)
android·java·spring
Wgllss1 小时前
Android Compose轻松绘制地图可视化图表,带点击事件,可扩展二次开发
android·架构·android jetpack
SHUIPING_YANG2 小时前
MySQL 慢查询日志开启与问题排查指南
android·mysql·adb
tracyZhang4 小时前
NativeAllocationRegistry----通过绑定Java对象辅助回收native对象内存的机制
android
vv啊vv4 小时前
使用android studio 开发app笔记
android·笔记·android studio
冯浩(grow up)5 小时前
使用vs code终端访问mysql报错解决
android·数据库·mysql