4. Hilt构建失败:Dagger版本与Hilt版本不兼容
这个问题我碰到过好多次了。每次升级Hilt或者Dagger的时候,心里都要咯噔一下——版本不匹配带来的编译错误,有时候错误信息还特别隐晦。你想想看,明明只是改了个版本号,AS瞬间给你刷出一整屏红色,多闹心。
4.1 你是怎么遇到这问题的?
最常见的就是下面这种报错:
Dagger does not support dependency injection with Hilt.
Hilt versions older than 2.40 require Dagger version 2.40.x or newer.
或者干脆编译崩溃,告诉你某个类找不到。为什么会这样?
说白了,Hilt 是基于 Dagger 的封装。它自己并不重写所有注解处理器,而是直接依赖 Dagger 的编译流程。Hilt 的核心库(hilt-android-gradle-plugin、hilt-android-compiler)内部声明了对特定 Dagger 版本的依赖。但如果你在项目里手动覆盖了 Dagger 版本号,就有可能打破这个约定。
NoSuchMethodError 或 TypeNotPresentException。
4.2 到底哪些版本能搭?
我建议你记住一个简单规律:
- Hilt 2.40 之前:Hilt 和 Dagger 的版本号必须完全一致。比如 Hilt 2.38.1 必须配合 Dagger 2.38.1。
- Hilt 2.40 到 2.44:Hilt 开始允许 Dagger 小版本号差异,但要求大版本号相同。例如 Hilt 2.40 可以配合 Dagger 2.40.x(x 任意),但不能用 Dagger 2.39。
- Hilt 2.45+:Hilt 和 Dagger 各自独立发版,但 Dagger 版本号 ≤ Hilt 版本号,且差距不超过两个小版本。官方文档说「接近即可」,我个人建议直接用
2.46.1配合2.46这种。
| Hilt 版本 | 推荐的 Dagger 版本 | 备注 |
|---|---|---|
| 2.38.x | 2.38.x | 必须完全对齐 |
| 2.40 ~ 2.44 | 2.40.x ~ 2.44.x | 大版本相同即可 |
| 2.45 ~ 2.46 | 2.45 ~ 2.46 | Dagger 版本 ≤ Hilt 版本,差不超过2 |
gradle.properties 里声明一个统一变量 dagger_version 和 hilt_version,然后所有模块都用这个变量。这样改版本号时不会漏掉。
4.3 怎么快速排查?
遇到编译报错别急着改代码。先确认你项目里到底用了哪些 Dagger 依赖。打开 Gradle 依赖树:
./gradlew :app:dependencies --configuration runtimeClasspath | grep -E "dagger|hilt"
看看输出结果里有没有多个不同的 Dagger 版本。如果同时出现了 2.40.1 和 2.39,那就是冲突爆炸。
还有一种更隐蔽的情况:第三方库内部的 Dagger 版本。比如有些旧版 Retrofit 或 Room 的依赖传递中包含了老版本的 Dagger。这时候你需要用 force 或者 exclude 来统一版本。
4.4 解决方案三步走
- 锁定 Dagger 版本:在项目级
build.gradle中强制使用与 Hilt 匹配的 Dagger 版本:
// 项目级 build.gradle
allprojects {
configurations.all {
resolutionStrategy {
force "com.google.dagger:dagger:2.46"
force "com.google.dagger:dagger-compiler:2.46"
force "com.google.dagger:dagger-android-support:2.46"
}
}
}
- 升级 Hilt 插件:有时候老老实实用最新版 Hilt 反而不会有版本冲突。
// 项目级 build.gradle
plugins {
id 'com.google.dagger.hilt.android' version '2.46' apply false
}
- 检查 Kotlin 版本:Hilt 的 Gradle 插件对 Kotlin 版本也有要求。如果 Kotlin 太低,可能间接触发 Dagger 兼容问题。我记得有一次我把 Kotlin 从 1.6 升到 1.8,冲突就莫名其妙消失了。
4.5 避坑指南
我曾经踩过的坑:
- 在模块中直接写
implementation 'com.google.dagger:dagger:2.44'而不是通过全局变量。后来升级 Hilt 时忘了改这里,花了半个小时 debug。 - 用了
hilt-android-testing和dagger-android-processor混合,结果测试模块的 Dagger 版本跟主模块不同。测试编译过了,运行时就崩。 - 相信了 Maven 仓库上的
latest.release占位符——结果解析出了不兼容的版本组合。
所以,我现在养成一个习惯:每次改 Hilt 版本号,先跑 ./gradlew dependencies 扫一遍 Dagger 相关依赖,确认没有版本漂移。别人问我为什么编译那么快,我说其实并不是快,而是多数问题在前面就被拦截了。
4.6 最后几句实话说
版本兼容问题,说白了就是「依赖管理」意识不够。Hilt 团队其实已经做了很多工作让版本尽量解耦,但项目里如果混用太多第三方库,迟早会撞上。我个人建议把 Hilt 和 Dagger 的版本号写在一个全局 ext 块里,并且在 CI 上跑个依赖检查脚本。嗯,这样能省很多事。
下次你看到 Dagger 编译报错,先别慌。去查版本号。百分之九十的情况都是版本没对齐。