Hilt 基本使用:@HiltAndroidApp 与 @AndroidEntryPoint
你拿到一个新项目,第一件事是什么?我习惯先把 DI 框架搭好。Hilt 的入口就两个注解:@HiltAndroidApp 和 @AndroidEntryPoint。别小看它们,一个没写对,整个依赖注入链就断了。
1. @HiltAndroidApp —— 应用的根
说白了,这就是 Hilt 的启动开关。你必须把它加到你的 Application 类上,而且只能加一次。我遇到过新手直接在 Activity 上用了 @HiltAndroidApp…… 嗯,编译直接报错。
@HiltAndroidApp
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// 可以在这里做初始化,但别把 Hilt 相关逻辑放这儿
}
}
这个注解干了三件事:
- 生成一个
Hilt_MyApplication基类 - 触发 Dagger 的 APT 处理器,扫描所有带
@AndroidEntryPoint的组件 - 创建顶层
SingletonComponent,管理整个应用的生命周期
个人习惯:我会在
@HiltAndroidApp 的 Application 里初始化一些日志、Crash 上报等非业务模块,但绝不要动 Hilt 生成的任何方法名。记住,Hilt 生成的类名以下划线结尾,比如 Hilt_MyApplication,你不需要手动调用它们。
2. @AndroidEntryPoint —— 组件的门票
每个需要用到注入的 Android 组件,比如 Activity、Fragment、Service,都要贴上这个注解。没有它,Hilt 根本不会碰你的类。我曾经在某个 Fragment 里忘了加,结果运行时空指针满天飞,排查了半天才发现是这个原因。
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var repository: MyRepository
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// repository 已经可以用了
}
}
注意几个关键点:
- 必须先写 super.onCreate() —— Hilt 在 super 调用里完成了注入,你在这之前访问
@Inject字段会报错 - Fragment 中的注入时机是
onAttach()结束后到onCreate()之间,所以你在onCreate()里用就已经安全了 - View、BroadcastReceiver 等组件不支持
@AndroidEntryPoint,需要别的处理方式(以后章节会讲)
我曾经踩过的坑:在
ViewModel 上用了 @AndroidEntryPoint。其实 ViewModel 应该用 @HiltViewModel。当时编译没报错,但运行时根本注不进去。记住:@AndroidEntryPoint 只适用于 Activity、Fragment、Service、BroadcastReceiver,别乱贴。
3. 它们之间的协作流程
先看这张图,你就清楚了:
4. 常用注解对比表
为了方便查阅,我把几个常用注解的职责列一下:
| 注解 | 作用目标 | 核心功能 |
|---|---|---|
@HiltAndroidApp |
Application 类 | 启动 Hilt,生成顶层组件,只能出现一次 |
@AndroidEntryPoint |
Activity, Fragment, Service, BroadcastReceiver | 为组件注入依赖,生成子组件 |
@HiltViewModel |
ViewModel 类 | 配合 Activity/Fragment 注入 ViewModel |
@Inject |
构造方法或字段 | 告诉 Hilt 这个对象需要被注入 |
5. 避坑指南
@HiltAndroidApp必须写在 Application 上,不能写在其他类。 我见过有人把它加在 BaseActivity 上,编译直接崩。- Activity 和 Fragment 的注入顺序有讲究: Fragment 在
onAttach()之后注入,所以不要把注入逻辑写在构造方法或onAttach()之前。 - 如果你用 Kotlin,
@Inject字段推荐用lateinit var,避免空检查。Java 的话就用@Inject修饰,Hilt 会帮你赋值。 - 多模块项目注意: 每个模块的
@HiltAndroidApp只能有一个,其他模块靠@Module提供依赖,不要重复写 Application 注解。
核心原则: Hilt 把 Dagger 的模板代码收走了,但底层原理一样。你只要记住 —— @HiltAndroidApp 是总开关,@AndroidEntryPoint 是分开关。两个都写对,注入才能通。