2. Hilt构建失败
1. 现象:构建日志突然红了
你正在愉快地写代码,点击运行,然后 Gradle 构建直接崩溃。错误日志里冒出一段提示:
error: [Dagger/MissingBinding]
dagger.hilt.android.internal.managers.ViewComponentManager
cannot be provided without an @HiltAndroidApp Application
或者更直白的:
AndroidManifest.xml does not declare an Application class
that is annotated with @HiltAndroidApp or extends HiltApplication
嗯,看懂了——Hilt 找不到正确的 Application 入口。我个人第一次碰到这个错的时候,第一反应是“我明明加了注解啊”,结果翻了一下 AndroidManifest.xml 才发现……压根没配置 Application 类。
2. 原因:少了“钥匙”还是“锁”不对?
| 问题类型 | 具体表现 |
|---|---|
| Application类未声明 | Manifest 中根本没有 android:name 字段,或指向了一个普通 Application 子类(未继承 Hilt 相关) |
| 继承错误 | 自定义 Application 继承自 Application 而非 HiltApplication,或忘记加 @HiltAndroidApp 注解 |
| 包名拼写错误 | Manifest 里写的是 .MyApp,但实际类名是 MyApplication |
说白了,Hilt 需要一个“总开关”——就是被 @HiltAndroidApp 标记的 Application 类。它负责生成依赖图的根组件。如果你没告诉它“入口在哪”,Dagger 就不知道从哪里开始装配。
3. 关键节点:@HiltAndroidApp 与 HiltApplication
Hilt 提供两种方式来指定你的 Application:
- 注解方式:在自定义 Application 类上直接加
@HiltAndroidApp,类本身可以继承Application(或其他基类)。 - 继承方式:让你的 Application 类继承
HiltApplication,此时 Hilt 会自动处理。
无论哪种方式,最终都需要在 AndroidManifest.xml 的 <application> 标签里写明 android:name。
我曾经见过一个项目,团队把 @HiltAndroidApp 加在了 Activity 上——那是错误的。Hilt 的根注解必须放在 Application 类上,否则编译能过,运行时必崩。
4. 标准操作:三步走
我们一步步来,我建议你按这个顺序排查:
// 第一步:创建 Application 子类,加上注解
@HiltAndroidApp
class MyApplication : Application() { }
// 第二步:在 AndroidManifest.xml 中声明
<application
android:name=".MyApplication"
... >
...
</application>
// 第三步:Rebuild 项目
./gradlew clean assembleDebug
就这么简单。但实际项目中往往因为混淆、multidex、或者库冲突导致问题。嗯,这里要注意:如果你的项目已经用了其他库提供的 Application 子类(比如 Firebase 的 FirebaseApp 初始化器),别慌,Hilt 允许你通过 @HiltAndroidApp 注解你自己的类,它并不要求你继承 HiltApplication。
5. 避坑指南:我曾经踩过的两个坑
- 坑一:Manifest 里写了全限定名但没加注解。 我有个朋友(其实就是我)把一个旧项目的 Application 类直接复制过来,忘了加
@HiltAndroidApp,结果构建一直报错。找了一下午才发现注解没写。 - 坑二:混淆导致类名丢失。 有一次我开了混淆,Application 类被重命名了,但 Manifest 里写的是原始名。构建虽然能过,但安装运行直接崩溃。我建议你在
proguard-rules.pro里加上:
-keep class * extends dagger.hilt.android.internal.managers.ViewComponentManager
-keep @dagger.hilt.android.HiltAndroidApp class *
6. 快速诊断清单
| 检查项 | 正确示例 | 错误示例 |
|---|---|---|
| Application 类是否存在 | app/src/main/java/.../MyApplication.kt | 没有对应的 .kt/.java 文件 |
| 是否添加 @HiltAndroidApp | @HiltAndroidApp | 漏写或写成了 @HiltViewModel |
| Manifest 中 android:name | android:name=".MyApplication" | 未写或写错包名 |
| Application 继承关系 | 可直接继承 Application()(有注解时)或继承 HiltApplication | 继承了 MultiDexApplication 却未处理 Hilt 初始化(需手动添加 @HiltAndroidApp) |
如果你用了 MultiDexApplication 或者第三方 BaseApplication,不要慌——直接在自定义类上加 @HiltAndroidApp,并继承你原来用的那个类。Hilt 不强制继承 HiltApplication。
7. 核心逻辑流程图
下面这张 SVG 图展示了从创建 Application 类到构建成功的完整路径——我经常拿它给团队新人做培训,一目了然。
总结一句话:@HiltAndroidApp 是钥匙,AndroidManifest.xml 是锁孔。两头都得对。