3. Hilt构建失败
这个问题,几乎所有用 Hilt 的人都遇到过。说白了就是你的 Gradle 脚本里忘了写 kapt,或者写的位置不对。Hilt 依赖 Annotation Processing Tool(APT)来生成那些注入代码,而 Kotlin 项目里这件事默认由 kapt 插件负责。你没声明它,编译器自然不知道要把 @HiltAndroidApp 这些注解转换成真正的依赖图。
为什么 Hilt 离不开 kapt?
Hilt 本质上还是 Dagger 的封装。Dagger 在编译期通过 APT 扫描 @Component、@Module、@Inject 等注解,然后生成一大波 _Factory、_MembersInjector 文件。Kotlin 项目里,Java 的 annotationProcessor 不认识 Kotlin 源码,所以 Google 官方提供了 kapt 插件——它先让 Kotlin 编译器解析源码,然后再把生成的桩代码交给 APT 处理器。
嗯,这里有个细节:kapt 只负责处理 Kotlin 文件中的注解。如果你的项目混合了 Java 和 Kotlin,还得加上 annotationProcessor 来覆盖 Java 部分?其实不用,Hilt 的所有注解都写在 Kotlin 里,一个 kapt 就够了。但我个人习惯把两者的依赖都写上,避免哪天混用。
常见错误清单
| 错误表现 | 根本原因 | 我的经验 |
|---|---|---|
Build 报错:Annotation processors must be explicitly declared now | 项目级 build.gradle 未应用 kotlin-kapt 插件 | 年轻时我在这卡了半小时,后来才反应过来是插件忘记写 |
| 运行时 Hilt 组件空指针 | 模块级 build.gradle 中漏了 kapt 依赖声明(如 kapt 'com.google.dagger:hilt-compiler:…') | 有一次同事把 kapt 写成了 implementation,注解处理器完全没触发 |
| Kotlin 版本与 kapt 不兼容 | 项目中 kotlin-gradle-plugin 版本和 kapt 版本不匹配 | 我个人建议用同一份 kotlin_version 变量,省事 |
编译报错:Unsupported class file major version | JDK 版本与 AGP / kapt 插件冲突 | 升级 JDK 17 后踩过这个坑,降回 11 就正常了 |
正确配置示范
咱们直接看代码。这是项目级 build.gradle(或 build.gradle.kts)的关键部分:
// 项目级 build.gradle
buildscript {
ext.kotlin_version = '1.8.0' // 统一版本
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// 确保 kapt 插件包含在内(其实 kotlin-gradle-plugin 就自带了)
}
}
然后模块级 build.gradle:
// app/build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt' // 这一行必须有
}
android {
// ...
}
dependencies {
implementation 'com.google.dagger:hilt-android:2.45'
kapt 'com.google.dagger:hilt-compiler:2.45'
// 其他依赖...
}
核心要点: kotlin-kapt 插件要在 plugins 块里声明,不能用旧的 apply plugin: 'kotlin-kapt' 方式(除非你还在用 Groovy 的老路子)。另外,hilt-compiler 必须使用 kapt 作用域,不能用 implementation,否则 APT 根本不会执行。
KSP 替代方案
最近 Google 推荐用 ksp(Kotlin Symbol Processing)替换 kapt,因为 kapt 在大型项目里编译速度慢。但 Hilt 对 KSP 的支持目前还属于实验阶段,稳定版还是得靠 kapt。如果你非要尝鲜,配置也类似:
plugins {
id 'com.google.devtools.ksp' version '1.8.0-1.0.9'
}
dependencies {
ksp 'com.google.dagger:hilt-compiler:2.45'
}
不过我曾经试过一次,KSP 版本和 Kotlin 版本没对齐,编译直接炸了。短期内我建议还是老老实实用 kapt,等到 Hilt 官方宣布 KSP 稳定再迁移。
SVG 流程图:Hilt 注解处理链路与失败点
避坑指南
我曾经…… 小心翼翼地把所有 Hilt 依赖都写成了 implementation,编译不报错,但 App 一运行就崩。查了半天发现 hilt-compiler 根本没用上。后来我养成了一个习惯:每次添加新依赖后,先跑一次 ./gradlew assembleDebug --info,看一眼输出里有没有 Annotation processing started 这样的日志,没有就说明 kapt 没生效。
一个小技巧: 在写模块级 build.gradle 时,把 kotlin-kapt 插件放在 com.android.application 后面,保持清晰。如果你的项目是多模块的,每个使用了 Hilt 的模块都得重复声明 kotlin-kapt 和 kapt 依赖。别觉得麻烦,这是标准做法。
另外,当你用 KTS(Kotlin DSL)写 Gradle 脚本时,kapt 的写法略有不同:
// build.gradle.kts
plugins {
id("com.android.application")
kotlin("android")
kotlin("kapt")
}
dependencies {
implementation("com.google.dagger:hilt-android:2.45")
kapt("com.google.dagger:hilt-compiler:2.45")
}
语法没问题。但是我注意到有些开发者会把 kapt 错写成 kapt("…") 但忘记加引号,或者括号括错了位置。你想想看,这些低级错误往往浪费最多时间。
如果还是解决不了
清除缓存试试:./gradlew clean 然后重新构建。有时候 Gradle 缓存了旧的 APT 输出,新的 kapt 插件没被识别。我推荐在项目根目录下执行:
./gradlew build --rerun-tasks
这个命令会强制重新执行所有任务,包括 kapt 的注解处理。如果仍然报错,就去检查你的 Android Gradle Plugin 版本和 Kotlin 插件版本是否匹配。AGP 7.x 系列一般推荐 Kotlin 1.7.x ~ 1.9.x,你可以参考官方兼容性表格。
好了,这一节就到这。记住一个口诀:先加插件,再写依赖,作用域用 kapt,版本要统一。你按这个顺序检查,几乎能解决 90% 的 kapt 配置问题。