一文带你了解 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 包体积优化实践------入门级攻略
相关推荐
你听得到1118 分钟前
肝了半个月,我用 Flutter 写了个功能强大的图片编辑器,告别image_cropper
android·前端·flutter
KevinWang_18 分钟前
Android 原生 app 和 WebView 如何交互?
android
用户693717500138420 分钟前
Android Studio中Gradle、AGP、Java 版本关系:不再被构建折磨!
android·android studio
杨筱毅1 小时前
【底层机制】Android低内存管理机制深度解析
android·底层机制
二流小码农2 小时前
鸿蒙开发:this的指向问题
android·ios·harmonyos
循环不息优化不止2 小时前
Jetpack Compose 状态管理
android
友人.2274 小时前
Android 底部导航栏 (BottomNavigationView) 制作教程
android
努力学习的小廉4 小时前
初识MYSQL —— 事务
android·mysql·adb
阿里云云原生4 小时前
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
android
.豆鲨包4 小时前
【Android】Android内存缓存LruCache与DiskLruCache的使用及实现原理
android·java·缓存