一文带你了解 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 包体积优化实践------入门级攻略
相关推荐
雨白2 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹4 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空6 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭6 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日7 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安7 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑7 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟11 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡13 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0013 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体