Hilt 是什么?我为什么要用它?
说起来,我第一次接触依赖注入的时候,跟很多人一样——觉得这东西可有可无。那时候手写单例、手动传参,项目小倒是没啥。直到有一次接手一个百万行级别的 App,光构造一个 ViewModel 就要牵扯七八个依赖,改一个接口得全局搜引用……嗯,那感觉,你懂的。
后来我遇到了 Hilt。说白了,Hilt 就是 Google 官方专门为 Android 打造的依赖注入框架,它站在 Dagger 的肩膀上,但帮你把很多繁琐的配置工作都省掉了。
核心一句话
Hilt 是一个在编译期生成代码的依赖注入容器,它知道每个对象该怎么创建、该活多久、该给谁用。
关键点: Hilt 的注入逻辑在编译时完成,运行时几乎没有反射开销。这对 UI 渲染性能至关重要——你想想看,如果每次绘制一帧都要跑去反射查找依赖,界面不卡才怪。
我为什么从 Dagger 换到 Hilt
早期团队用的是原生的 Dagger 2。说实话,Dagger 2 本身很强大,但用起来太「硬核」了——你得手动创建 @Component、@Subcomponent,还得在 Application 里初始化。有一次我重构一个模块,漏掉了 @Component.Factory 的绑定,结果编译错误信息长达两百行……定位问题花了整整一下午。
Hilt 把这一切简化了:
- 你只需要在 Application 类上加上
@HiltAndroidApp - 在 Activity / Fragment 上加上
@AndroidEntryPoint - Hilt 自动帮你生成并管理组件树
一个典型的对比表格:
| 对比项 | Dagger 2 | Hilt |
|---|---|---|
| 组件初始化 | 手动创建 @Component、手动调用 .create() |
自动生成,只需 @HiltAndroidApp |
| 作用域 | 自己定义 @Scope,容易配错 |
内置 @Singleton、@ActivityScoped 等,直接使用 |
| Android 生命周期绑定 | 需要手动管理,容易内存泄漏 | 自动跟随 Activity/Fragment 生命周期 |
| 学习成本 | 高,需要理解 @Component、@Module、@Binds 等大量概念 |
低,掌握 @HiltAndroidApp、@AndroidEntryPoint、@Inject 足以入门 |
| 编译速度 | 大型项目编译较慢(全量生成) | 增量编译,第一次构建后速度明显提升 |
避坑指南: 我曾经在一个项目中直接用 @Singleton 标注了所有的依赖,结果导致 ViewModel 在每次屏幕旋转后都不会重新创建,旧数据一直残留在内存里,界面刷新完全错乱。Hilt 的默认作用域是随着组件生命周期走的,千万别滥用 @Singleton。
Hilt 的核心概念(三句话讲清楚)
你不用一次性记住所有细节,先有个印象就行:
- 组件(Component): 每个 Android 组件(Application、Activity、Fragment、Service 等)都对应一个 Hilt 组件,负责管理依赖的实例。
- 模块(Module): 告诉 Hilt 如何创建那些你不能直接
@Inject构造函数的类(比如 Retrofit 的OkHttpClient)。 - 入口点(EntryPoint): 标记哪些 Android 类需要注入,比如
@AndroidEntryPoint的 Activity。
下面这张图把 Hilt 在 Android 应用里的位置和核心流程画出来了——你会发现依赖注入并不神秘,它只是把「谁创建谁」的责任交到了一个统一的地方。
给新手的话: 上面这张图里,你重点关注两个地方就好——第一是 @HiltAndroidApp 和 @AndroidEntryPoint,它们负责「开关」;第二是下面的「编译时生成注入代码→零反射」,这是 Hilt 不影响 UI 渲染速度的根本原因。
为什么选择 Hilt 来做 UI 渲染排查?
你可能要问:依赖注入跟 UI 渲染有啥直接关系?
我举个例子你就明白了。有一次线上反馈说某个详情页打开特别慢,按返回键再进一次又快如闪电。排查后发现是依赖注入的锅——那个页面的 ViewModel 在构造函数里调了一个网络请求去拿远程配置,而这个请求被 @Singleton 缓存了,第二次打开时不需要网络。但第一次打开时,网络请求阻塞了 onCreate(),导致 UI 渲染帧率断崖式下跌。
你看,依赖注入的生命周期管理直接影响了页面的创建速度。如果 Hilt 配置不当,依赖创建的耗时就会变成 UI 渲染的隐形杀手。所以我们这个课程,就是教你如何用 Hilt 提供的工具(组件树、作用域、模块编排)来定位和优化这类问题。
重要提醒: Hilt 本身不会让 UI 变慢,但你不合理的注入写法(比如在 @Singleton 里创建大对象、在 @ActivityScoped 里做耗时初始化)会拖慢组件创建。排查的时候,先怀疑你的 Hilt 配置,再怀疑框架本身。
接下来我们怎么学?
本课程一共 30 章,我会从最简单的 @Inject 用法开始,逐步深入到自定义组件、跨模块注入、性能 profiling 工具,最后用几个真实案例带你手把手排查 UI 渲染中的依赖注入开销。