4. 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 版本号,就有可能打破这个约定。

⚠️ 注意: 这不是简单的「编译时警告」,而是严重的二进制不兼容。Hilt 编译期生成的代码里,直接调用了 Dagger 内部 API,API 签名哪怕只差一个参数类型,都会导致 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 解决方案三步走

  1. 锁定 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"
        }
    }
}
  1. 升级 Hilt 插件:有时候老老实实用最新版 Hilt 反而不会有版本冲突。
// 项目级 build.gradle
plugins {
    id 'com.google.dagger.hilt.android' version '2.46' apply false
}
  1. 检查 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 相关依赖,确认没有版本漂移。别人问我为什么编译那么快,我说其实并不是快,而是多数问题在前面就被拦截了。

Hilt ↔ Dagger 版本兼容检查流程 检查 Hilt 版本 Hilt 版本 < 2.40 ? 是 Dagger版本必须完全一致 否 Hilt >= 2.40 ? 深度检查 运行 gradle dependencies 确认实际解析版本 统一版本 → 构建成功 关键:排除传递依赖中的旧 Dagger 使用 resolutionStrategy.force 锁定

4.6 最后几句实话说

版本兼容问题,说白了就是「依赖管理」意识不够。Hilt 团队其实已经做了很多工作让版本尽量解耦,但项目里如果混用太多第三方库,迟早会撞上。我个人建议把 Hilt 和 Dagger 的版本号写在一个全局 ext 块里,并且在 CI 上跑个依赖检查脚本。嗯,这样能省很多事。

下次你看到 Dagger 编译报错,先别慌。去查版本号。百分之九十的情况都是版本没对齐。