0%

2026 版 Android 构建提速:Configuration Cache、KSP2 与构建扫描实战

2016 年 5 月,我们在《Android Gradle 最佳实践》系列里连载到第 8 篇与第 9 篇(系列 8、系列 9)——那是 Gradle 2.x 的年代,”构建提速”聊的还是 daemon、并行与增量编译这些基础设施。十年过去,工具链的进化把话题的根基换掉了:Gradle 9.0(2025-07-31 发布)起 Configuration Cache 默认启用(Gradle 官方 release notes,docs.gradle.org,2025-07-31);AGP 9.0 又把运行时依赖的 KGP 拉到 2.2.10,项目里低于 2.2.10-2.0.2 的 KSP 插件会被自动升级(AGP 9.0 官方 release notes,developer.android.com,9.0.0 于 2025 年末发布、9.0.1 于 2026-01 发布)。”要不要打开提速开关”这个十年老问题,在 2026 年变成了”能不能活着完成升级”。

本文的写法与前几篇一致:数据全部来自 Gradle、Google、JetBrains 的官方文档与一手工程报告,口径与样本量逐一标注;个别未能全文核对的数字(部分官方博客页面为 JS 动态渲染,本环境抓不到全文)会明确标出”建议人工复核”,不把存疑数字写成确证事实。我自己的贡献是把这些散落的官方结论按新基线重新排序:版本演进先说清楚,再依次过 Configuration Cache、KSP2 与 KAPT 清理、构建扫描、CI 缓存四件事,每件给可执行的结论。

Key Takeaways

  • 2026 年的构建提速是新基线问题:Gradle 9.0 起 Configuration Cache 默认启用、全部插件要求兼容(2025-07-31),AGP 9.0 又把 KSP 自动拉到 2.2.10-2.0.2——"打开关"变成了"过升级关",迁移顺序要按新基线重排。
  • Configuration Cache 的收益机理是跳过整个配置阶段,AGP 8.1(2023-07)起 fully supports;迁移坑高度模式化——执行期持有 Project、File、脚本闭包三类,解法是改注入 Property 与服务,诊断入口是 --configuration-cache-problems=report。
  • KSP2 绕开 KAPT"先生成 Java stub 再交给 javac"的两遍解析,官方口径最高快 2 倍(up to,非均值);Google 一手案例:Maps 增量 -15%、Play Store clean -22%/增量 -24%(2024-12 官方博客,发布前建议复核原文)。
  • 先量再修:--profile 与 Build Scan 分清配置/执行占比,Build Analyzer 给出 GC 加堆(占比 >15% 时按 4/6/8 GB 逐档试)与 config cache 预检,Gradle Profiler 做 A/B 基准;经验上增量构建里配置阶段占比会明显放大,这正是 config cache 的收益场景。
  • CI 缓存三层分开配置:build cache(local + remote,注意 relocatability)、setup-gradle 的 Gradle User Home 缓存(matrix 下只允许一个 job 写、注意 10GB 配额)、configuration cache 条目用 cache-encryption-key 加密落盘。

新基线:默认开启的 Configuration Cache 与被 AGP 绑死的版本线

Gradle 9.0 带来的不是又一个优化选项,而是默认行为的改变。三条官方事实:其一,Configuration Cache 默认启用(Gradle 官方 release notes,docs.gradle.org,2025-07-31);其二,要求 Android 构建使用 AGP 8.0 以上、全部插件兼容 configuration cache(Gradle 9.0 Configuration Cache 文档,docs.gradle.org,2025-07);其三,Windows 平台上 task 执行比 8.14 快 5–10%(同 release notes,官方数字,平台限定 Windows)。默认化不是拍脑袋:它在官方 roadmap 里的状态是 Shipped(roadmap.gradle.org,2026-10-30 核对),而且 Gradle 8.11 起连 gradle init 生成的新项目都在根 gradle.properties 里默认写入 org.gradle.configuration-cache=true(Gradle 8.11 release notes,docs.gradle.org,2026-10-30 核对)——新项目已经出生在 config cache 的世界里了。

AGP 侧的联动同样硬。时间线:AGP 8.0 对 configuration cache 只有部分支持,AGP 8.1(2023-07)起官方宣布 fully supports(AGP 8.1 release notes,developer.android.com,2023-07);AGP 9.0 最低要求 Gradle 9.1.0(AGP 兼容矩阵,developer.android.com,持续更新),并内置了 Kotlin 支持——旧路径由 com.android.legacy-kotlin-support 插件承接,迁移或 opt-out 二选一(AGP 9.0 release notes,developer.android.com);到 2026 年 9/10 月的 AGP 9.5.0,最低 Gradle 已抬到 9.6.0、JDK 17(AGP 9.5.0 release notes,developer.android.com,2026)。也就是说,想留在”不开 config cache”的老世界,你得同时放弃 Gradle 9 与 AGP 9 两条线——对大多数团队这不现实。

底层性能在同步爬坡。Gradle 8.11 重做了并行任务执行调度:worker 线程完成任务后立即领取下一个任务,不再等待同一 project 的全部任务完成(Gradle 8.11 release notes,docs.gradle.org,2024-Q4,精确日期未核实);Gradle 9.1(2025-11)在 Windows 上默认启用 file system watching,构建延迟最高改善约 10%(Gradle 9.1 release notes,docs.gradle.org,2025-11)。Kotlin 侧,Kotlin 2.2.0 的 KGP 改进了 configuration cache 的序列化,最高带来 8% 构建提速(JetBrains 官方博客,blog.jetbrains.com,2025-06-23,未注明样本项目规模)。JetBrains 用 Develocity 对同一构建场景做过跨版本对比:Gradle 8.12 约 3.37 秒、9.0 约 2.63 秒(InfoQ 报道引述,infoq.com,2025-08)——单一小型构建场景,只作量级参考,别拿它外推自己的项目。

2023–2026 构建工具链关键版本时间线 横向时间线,上轨为 Gradle 与 Kotlin 版本节点,下轨为 AGP 与 Kotlin 版本节点。高亮两个 2026 关键转折:Gradle 9.0(2025-07-31)默认启用 Configuration Cache;AGP 9.0(2025 末至 2026-01)把项目 KSP 自动升级到 2.2.10-2.0.2。 Gradle 8.1 CC 转正 stable 2023 AGP 8.1 fully supports CC 2023-07 Kotlin 2.0.20 KSP2 捆绑进发行版 2024-08 Gradle 8.11 并行任务调度重做 2024-Q4 Kotlin 2.2.0 KGP CC 序列化提速 8% 2025-06-23 Gradle 9.0 CC 默认启用 2025-07-31 Gradle 9.1 Windows 文件监视 ≈10% 2025-11 AGP 9.0 KSP 自动升级到 2.2.10-2.0.2(KSP2) 2025 末–2026-01 青 = Gradle · 蓝 = Kotlin/AGP · 黄 / 红 = 2026 关键转折
图 1:2023–2026 构建工具链关键版本时间线。Gradle 9.0(2025-07-31)起 Configuration Cache 默认启用;AGP 9.0 把项目 KSP 版本线拉到 2.2.10-2.0.2。

顺带交代生态节奏。Kotlin 2.3.0(2025-11)继续在 K2 类型推断与 API 分析上做改进,Kotlin/Wasm、Kotlin/Native 各有最高 2 倍与 2.5 倍的提速(JetBrains 官方博客,blog.jetbrains.com,2025-11)——后两者与 Android JVM 构建没有直接关系,但它们说明 K2 前端仍在持续加码,而 KGP 与 KSP 的版本线都跟着 Kotlin 走。Gradle、AGP、Kotlin 三条线的升级节奏从此要一起规划,这也是本文后面两节的主线。

Configuration Cache:它省掉什么,向你索取什么

先回到机理。一次 Gradle 构建分三段:init、configuration、execution。配置阶段执行所有 build script、注册并配置 task、解析依赖图——一个多模块 Android 项目的配置阶段可能要执行上万行脚本逻辑。Configuration Cache 做的事,是把整个配置阶段的结果(task graph 及其配置输入)序列化落盘,下次构建若配置输入没变,直接反序列化进入执行阶段——整个配置阶段被跳过(Gradle 官方文档:”skip the configuration phase entirely”,docs.gradle.org,2026-10-30 核对)。官方没有给”单项提速多少秒”的通用数字,收益与构建配置逻辑的复杂度成正比:模块越多、脚本越重,省得越多。

代价是一份新契约:所有在配置期创建、执行期使用的对象必须可序列化。这就是迁移坑的全部来源。好消息是坑高度模式化,Gradle 官方维护了完整的修复建议文档,Android 官方也给出了起步配置:

1
2
3
4
5
6
7
8
# gradle.properties —— Configuration Cache 起步配置(Android 官方口径)
# Gradle 9.0 起默认为 true,8.x 项目从这里开始;显式写出以明确意图
org.gradle.configuration-cache=true
# 迁移期先 warn 观察问题清单,稳定后再收紧
org.gradle.configuration-cache.problems=warn
# build cache 与并行是另外两组独立开关,建议一起打开
org.gradle.caching=true
org.gradle.parallel=true

从官方问题清单里,我按日常撞到的概率挑出 9 条:

# 坑 症状 解法 官方出处
1 任务执行期访问 Task.project 报 cannot serialize object of type ‘org.gradle.api.Project’ 改用注入服务:ProviderFactory、ObjectFactory、ExecOperations、FileSystemOperations Gradle configuration cache 文档
2 task 字段直接持有 File/InputStream 等不可序列化对象 cannot serialize java.io.File… 字段改 RegularFileProperty/DirectoryProperty,或用 String 存路径 同上
3 lambda/闭包捕获脚本对象(如 it.file.absolutePath 导航链) cannot serialize Gradle script object references 状态封装进独立类,或在配置期求值为 Property<T> 同上
4 配置期文件系统探测(Gradle 8.1+ 输入跟踪) File.exists() 等被记录为配置输入,文件一变就 cache miss,难排查 用 report 定位探测点,减少配置期文件系统调用 Android Optimize your build
5 第三方插件不兼容(KAPT、部分发布/静态检查插件) 构建失败或缓存全 miss 按官方 incompatibilities 章节与插件自身文档逐个排查;KAPT 场景过渡期 kapt.use.worker.api=false(社区口径) Gradle configuration cache 文档
6 KSP 与 KAPT 混用 + configuration cache 直接构建失败(TaskExecutionException 类故障) 迁移期尽快把全部处理器统一切到 KSP google/ksp#1805
7 Tooling API / composite builds 部分场景 IDE 同步等场景异常 按官方 incompatibilities 章节逐条排查 Gradle configuration cache 文档
8 8.6 起问题报告行为收紧 升级后此前可压制的问题开始失败 迁移期 problems=warn 先观察,稳定后收紧 Gradle configuration cache 文档
9 Gradle 9.0 默认开启 老项目升级直接失败 逃生口 --no-configuration-cache;升级前先在 8.x 清干净 Gradle 9.0 release notes

两条使用建议。第一,诊断先于猜测:./gradlew --configuration-cache-problems=report 会生成 HTML 报告(build/reports/configuration-cache/ 下),每条问题可点击跳到出问题的代码行,另有 org.gradle.configuration-cache-report 插件可查看序列化值明细(Gradle 官方文档,docs.gradle.org)——比盯着 stack trace 猜快得多。第二,升级 Gradle 9 之前先在 8.x 上把 problems=warn 跑干净:Gradle 8.6 起报告行为改为只对真正影响缓存结果的问题失败(Gradle 官方文档,docs.gradle.org,2024),你看到的告警清单就是升级后的炸点清单。

Gradle 9 时代的逃生口仍然在:命令行加 --no-configuration-cache,或写 org.gradle.configuration-cache=false(Gradle 9.0 release notes / configuration cache 文档)。但注意定位——逃生口是给”插件还没修完”的过渡期用的,不是给”不想修”用的:每次逃生都意味着这次构建放弃跳过配置阶段的全部收益。另外,Android Studio 的 Build Analyzer 会在项目上跑一系列测试构建来预判 configuration cache 兼容性(Android 官方 “Optimize your build speed”,developer.android.com),升级前先用它预检一遍,比上线后救火体面。Gradle 官方还出过一期视频专讲 configuration cache 的改进与 Gradle 9 就绪情况,Gradle Configuration Cache: 2x faster, 4x smaller, and ready for Gradle 9.0(Develocity 官方频道)——视频标题口径,具体数字仍以官方文档为准。

最后是预期管理。翻遍官方渠道,configuration cache 没有一个”提速 X%”的通用数字——这不是文档缺失,而是收益本身强依赖项目形态:脚本越重、模块越多,被跳过的配置阶段越值钱;脚本很轻的小项目,收益可能感知不到。市面上能看到的大厂数字(Netflix、Shopify 之类)几乎都是 build cache、并行、构建扫描等组合拳的整体口径,不是 configuration cache 的单项数据。所以别拿别人的百分比立项:用后文 Gradle Profiler 的做法拿自己的 A/B 基线,数字才有意义。

KSP2 与 KAPT 清理:AGP 9.0 把迁移顺序定死了

KAPT 慢的原因在架构上就写死了:它先为 Kotlin 代码生成 Java stub,再把 stub 交给 javac 的注解处理器跑一遍——等于把你的 Kotlin 代码解析了两遍(Google 官方迁移文档,developer.android.com)。KSP(Kotlin Symbol Processing)直接分析 Kotlin 源码,官方口径是编译 Kotlin 代码时最高快 2 倍——注意这是 “up to” 的上限口径,不是均值,别拿它当预期收益写进排期。

2024 年 12 月,Google 在 Android Developers 官方博客披露了两个内部大项目的 KSP2 迁移数字:Google Maps 增量构建提速 15%;Google Play Store clean 构建 22%、增量构建 24%(Android Developers 官方博客 “Accelerating Builds with KSP2”,android-developers.googleblog.com,2024-12;该页面为 JS 动态渲染,本文数字经两路搜索摘要交叉验证一致,发布前建议人工点开原文复核)。这两个案例的含金量在样本:Maps 与 Play Store 都是 Google 内部最大型的多模块 Android 项目之一,不是 Demo。更早的 KSP2 preview 时期,官方在 Now in Android 样例项目上做过 KSP1 与 KSP2 的基准对比,逐项百分比未能全文核对(原文见 Medium androiddevelopers 专栏,复现入口见 Nia issue #369,待人工复核)。

KSP2 的架构变化值得一句:它基于 Kotlin Analysis API 与 K2 编译器前端构建,脱离 K1 前端绑定,注解处理器不再与具体编译器版本强耦合(KSP 官方文档,kotlinlang.org)。时间线上,Kotlin 2.0.20(2024-08)起 KSP2 捆绑进 Kotlin 编译器发行版;但 KSP 2.1.0 系列(2024 末)里 KSP2 仍是 opt-in(ksp.useKSP2=true),维护者在 issue 里确认仍在处理 KSP1 兼容长尾,截至 Kotlin 2.1.20 未默认(google/ksp releases 与 issue #2394)——直到 AGP 9.0 出手,把 opt-in 变成了事实默认。

这才是 2026 年迁移 KSP2 的真正触发器:AGP 9.0 运行时依赖 KGP 2.2.10,项目里的 KSP 版本若低于 2.2.10-2.0.2,AGP 会自动把它升级到该版本以匹配 KGP(AGP 9.0 官方 release notes,developer.android.com,官方原文确认)。2.2.10-2.0.2 属于 KSP2 版本线——你的 KSP2 迁移什么时候发生,不是由你决定,而是由你什么时候升 AGP 9.0 决定。

清理 KAPT 的顺序因此变得清晰。处理器侧的支持早已到位:Room 2.6.0(2023-10)起稳定支持 KSP,更早的 Room 2.4.0(2022-01 stable,KSP 为实验性)首次引入(AndroidX Room releases,developer.android.com,日期 2026-10-30 核对);Dagger/Hilt 的 KSP 支持由 2.48(2023-08-30)起以 alpha 引入,官方文档口径的 stable 里程碑为 2.60(2026-06,配套要求 KSP 2.3.9+)(Dagger 官方 changelog,github.com/google/dagger/releases,日期 2026-10-30 经 GitHub Releases API 核对;stable 口径见 dagger.dev KSP 指南,2026-10-30 核对)。而 KAPT 那边,JetBrains 在 KSP 2.0.0 发布时明确宣布进入 maintenance mode:只收关键 bug 修复,强烈建议迁移 KSP(JetBrains 官方博客,blog.jetbrains.com,2024-07)。

顺序为什么不能反?推演两条路径。先升 AGP 9.0:Gradle 9.1+ 与默认开启的 configuration cache 一起进来,此时项目里若还有 kapt——kapt 与 configuration cache 本就存在不兼容场景,社区 workaround 是 kapt.use.worker.api=false(Tier 3 社区口径,仅作过渡);更糟的是 KSP 与 KAPT 混用加 configuration cache 会直接构建失败(google/ksp#1805,2023–2024)。带着 KAPT 升级等于同时踩两颗雷。反过来,先在 Gradle 8.x 上把 kapt 清干净再升级:处理器替换不依赖 AGP 版本,清完之后升 AGP 9.0,KSP 自动就位、config cache 默认打开也不再有雷。想看 KSP 与 KAPT 的完整对比,Android Worldwide 的这场演讲值得一看:Fact or kapt? Build your next annotation processor with KSP(David Rawson)。

动手替换时还有两个注意。其一,逐模块替换本身是允许的,但如前所述 KSP/KAPT 并存加 configuration cache 会炸——替换要么赶在 config cache 开启之前完成,要么一次性全清,别停在混合态。其二,KSP1 到 KSP2 生成代码可能存在细微行为差异,AGP 9.0 自动升级完成之后,把 Room、Hilt 相关模块的编译与运行回归跑一遍,不要默认无缝。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// build.gradle.kts(模块级)—— kapt → ksp 迁移
plugins {
id("com.google.devtools.ksp")
// 版本与 Kotlin 版本配对,如 2.2.10-2.0.2(AGP 9.0 生态会自动对齐)
// 迁移完成后移除:id("org.jetbrains.kotlin.kapt")
}

dependencies {
// 修前(KAPT 两遍编译:先生成 Java stub,再交给 javac 注解处理器)
// kapt("androidx.room:room-compiler:2.6.1")
// kapt("com.google.dagger:hilt-compiler:2.60")

// 修后(KSP 直接分析 Kotlin 源码)
ksp("androidx.room:room-compiler:2.6.1")
ksp("com.google.dagger:hilt-compiler:2.60")
}
KSP2 迁移顺序流程图 五个步骤依次相连:一、清理 KAPT(kapt 换 ksp,移除 kotlin-kapt,在 Gradle 8.x 完成);二、预检兼容性(Build Analyzer 与 problems=warn);三、升级 AGP 9.0 与 Gradle 9.1 以上,KSP 自动升到 2.2.10-2.0.2;四、验证 KSP2 行为;五、用 Gradle Profiler 拿 A/B 基准数字。步骤三为关键转折。 1 · 清理 KAPT kapt(...) → ksp(...) 移除 kotlin-kapt 插件 Room ≥ 2.6 / Hilt ≥ 2.60 在 Gradle 8.x 上完成 2 · 预检兼容性 Build Analyzer 体检 problems=warn 跑一轮 查官方兼容库 3 · 升 AGP 9.0 Gradle 升 9.1+ KSP 自动升到 2.2.10-2.0.2(KSP2) config cache 默认开 4 · 验证 KSP2 clean / 增量对比 处理器行为回归 处理 KSP1 长尾 5 · 拿基准数字 Gradle Profiler --benchmark A/B 开 / 关各跑 10 次 中位数进汇报 AGP 9.0 联动约束:项目 KSP 版本低于 2.2.10-2.0.2 时,会被自动升级到该版本以匹配 KGP 2.2.10 顺序颠倒的代价:带着 KAPT 升 Gradle 9,会同时踩 KAPT×configuration cache 与 KSP/KAPT 混用两颗雷
图 2:KSP2 迁移顺序。AGP 9.0 的联动约束反过来决定了清理工作必须先做:先清 KAPT,再动版本线。

先量再修:–profile、Build Scan、Build Analyzer 与 Gradle Profiler

没有基线的优化全是玄学。构建提速最常见的返工,是拿着别人的清单挨个试开关,最后说不清哪条起了作用、哪条纯属安慰剂。测量工具链 Gradle 已经备齐,按投入成本从低到高:

--profile:零成本的本地报告。 任何一次构建加 ./gradlew --profile,就会在 build/reports/profile/ 下生成本地 HTML 报告,分节列出配置阶段与任务执行阶段的耗时(Gradle 官方文档,docs.gradle.org)。先看这一眼,就知道你的构建是”配置贵”还是”执行贵”——这决定后面该修 config cache 还是该修任务图。

Build Scan:共享与深挖。 Build Scan 的 Performance 页提供任务执行时间排行(含 UP-TO-DATE 与 FROM-CACHE 任务计数)、配置阶段总耗时与分项目耗时,Timeline 视图可视化任务与配置间隙(Gradle 官方文档,docs.gradle.org;scans.gradle.com)。报告可上传、链接可共享,适合团队场景;商业版 Develocity 在 Gradle 9 时代还加上了 configuration cache miss 原因报告与 artifact transform 洞察(gradle.org,2025,商业产品能力,口径注明)。

Build Analyzer:Android 专属体检。 Android Studio 的 Build Analyzer(View > Tool Windows > Build)会给出:缺失或多余的 daemon、动态版本依赖、按插件维度的编译耗时分布(Java/Kotlin/dexing),以及两条最值钱的建议——GC 占构建时间超过 15% 时增大 JVM 堆(官方建议按 4/6/8 GB 逐档试),以及用 KSP 替代 kapt(Android 官方文档,developer.android.com 与 optimize-your-build)。前文的 configuration cache 预检也在这里。

Gradle Profiler:拿得出手的 A/B 基准。 官方基准工具,支持 --benchmark 模式、warm-ups 与迭代次数定义、GC 与系统性能采样,输出 Chrome Trace 与火焰图(gradle/gradle-profiler)。开/关 config cache 各跑 10 次、取中位数对比——这种数字才能进汇报。

时间都花在哪,社区有一个可以建立量级感的构成:clean 构建里任务执行约 60–85%、配置阶段 10–25%、init 1–5%;增量构建里配置阶段占比会明显膨胀到 30–60%,因为任务执行被增量机制吃掉了大半;lint 单项可占 15–30%(社区观察口径,非官方统计,仅作背景)。方向是可信的:构建越”熟”(增量、缓存命中),配置阶段的相对成本越高——这正是 configuration cache 的收益场景,也是 Gradle 敢把它默认化的底气。这组量级还有个实际推论:配置占比高的项目,优化重点是 config cache 与脚本瘦身;任务执行占比高的,重点转向增量、build cache 与砍掉 lint 这类昂贵任务——先看自己的图,再选工具。

构建时间构成:clean 与增量的经验量级 两条横向堆叠条形。clean 构建条:init 约 3%(范围 1–5%),配置阶段约 17%(范围 10–25%),任务执行约 80%(范围 60–85%)。增量构建条:配置阶段约 45%(范围 30–60%),任务执行约 55%。图内标注经验量级、非官方统计。 init 配置阶段 任务执行 clean 构建(冷启动) 配置 17% 任务执行 80% init ≈3% 范围:init 1–5% · 配置 10–25% · 任务执行 60–85% 增量构建 配置 45% 任务执行 55% 范围:配置 30–60% · 任务执行为剩余部分(约 35–70%) 经验量级,非官方统计——社区观察口径,用于建立方向感,不作为精确账本
图 3:构建时间构成的经验量级(社区观察口径,非官方统计)。增量构建里配置阶段的相对成本放大,这是 configuration cache 收益的来源。

CI 缓存:三层结构、一个 matrix 坑与可复制的 workflow

先把三样容易混的东西分开:configuration cache 缓存的是配置阶段结果(task graph),build cache 缓存的是任务输出,setup-gradle 管的是 Gradle User Home(wrapper 发行版、下载的依赖、configuration cache 条目)。三层各管一段,配置方式互不替代。

build cache:local 与 remote 两级。 org.gradle.caching=true 或 --build-cache 启用;默认只有 local,remote 在 settings.gradle.kts 里配 buildCache(Gradle 官方文档,docs.gradle.org)。remote 的关键约束是 relocatability(可重定位性):任务输出路径必须是相对的,否则换一台机器路径对不上、命中即失效。CI 与本地通常配成”CI 推、本地只拉”:

1
2
3
4
5
6
7
8
9
10
// settings.gradle.kts —— remote build cache(Gradle 官方文档口径)
buildCache {
local {
isEnabled = true
}
remote<HttpBuildCache> {
url = uri("https://cache.example.com/cache/")
isPush = System.getenv("CI") != null // CI 推、本地只拉,避免污染远端
}
}

setup-gradle:GitHub Actions 上的默认缓存层。 官方 action(gradle-build-action 的继任者)默认缓存整个 Gradle User Home——wrapper 发行版、caches/modules-2 的依赖、configuration cache 条目;cache key 基于 **/*.gradle*、**/gradle-wrapper.properties、**/gradle.properties 等文件的哈希,支持 restore-keys 前缀匹配,并内置过期缓存清理(gradle/actions 官方仓库,github.com/gradle/actions,当前 v4/v5 系列)。job summary 里会直接输出缓存命中与恢复大小报告,命中率好不好一眼可见。另外别低估 local build cache:同一台机器上跨分支切换、重跑 clean build 时,任务输出能直接从缓存复活,这些场景没有 remote 也受益。把 job summary 的命中率当 CI 的健康指标定期看——命中率突然下滑,多半是有人动了 gradle.properties 或 wrapper,比等构建变慢再排查主动得多。

matrix 与配额:最容易踩的坑。 GitHub Actions 每仓库缓存配额 10GB(GitHub Actions 官方文档,docs.github.com)。多 OS matrix 下每个 job 各写一份缓存,三份 Gradle User Home 很快挤爆配额、互相驱逐。官方最佳实践是只允许一个 job 写缓存,其余只读;feature 分支也建议 cache-read-only: true。configuration cache 条目可能含敏感值,官方提供 cache-encryption-key 用 secret 加密落盘(github.com/gradle/actions)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# .github/workflows/android-ci.yml —— 三层缓存的完整写法
name: android-ci
on: [push, pull_request]

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4

- uses: gradle/actions/setup-gradle@v4
with:
# matrix 下只允许 ubuntu 这一个 job 写缓存,其余只读,
# 避免 3 份 Gradle User Home 挤爆仓库 10GB 配额(官方最佳实践)
cache-read-only: ${{ matrix.os != 'ubuntu-latest' }}
# configuration cache 条目可能含敏感值,用 repo secret 加密后落盘
cache-encryption-key: ${{ secrets.GRADLE_CACHE_ENCRYPTION_KEY }}

- run: ./gradlew build

命中率值多少时间?官方没有给出通用的命中率或提速数字——命中率由三个因素决定:任务的 relocatability(输出路径必须相对化)、cache key 粒度、以及构建之间的重复度(Gradle 官方 build cache 文档,docs.gradle.org)。这个决定因素反过来就是缓存的边界:分支间差异越大、构建间共享的输入越少,缓存越接近失效——所以 remote cache 值不值得立项,必须用自己的构建做 A/B(后文 Gradle Profiler 的做法),别拿别人的百分比排期。厂商侧的数字全部按客户证言口径引用,别当实测基准:Curology 的 remote cache 命中率 70–80%、CI 构建 9 分钟降到 4.5 分钟(Gradle 客户案例引述,gradle.com);Netflix 构建时间削减 60%+、LinkedIn CI 构建时间 -40%、Charter CI 时间 -85%+——这些是”build cache + build scan 等组合拳”的整体优化证言,不是单项数据。

这套”默认缓存、显式 key、写入权收敛、给度量留报告位”的思路,与上个月变异测试那篇的 CI 门禁设计是同一个工程直觉:自动化设施的可信度,取决于它自己有没有被治理(用变异测试给 AI 生成的测试打分)。缓存治不好命中率,变异门禁防不住假测试,是同一件事:先有度量,再谈加速。

FAQ

Gradle 9.0 默认开启了 Configuration Cache,还能关掉吗? 能。临时关:命令行加 --no-configuration-cache;项目级关:org.gradle.configuration-cache=false(Gradle 9.0 release notes)。但建议把它当逃生口而不是常态——关闭即放弃跳过配置阶段的全部收益,IDE 日常构建也会跟着慢。正确姿势是按坑清单逐条修插件,用 --configuration-cache-problems=report 定位。

KSP2 与 KSP1 到底差在哪?现在必须切 KSP2 吗? 架构上 KSP2 基于 Kotlin Analysis API 与 K2 编译器前端,处理器不再与 K1 强耦合(kotlinlang.org)。”是否必须”由 AGP 9.0 替你回答:它会把低于 2.2.10-2.0.2 的 KSP 自动升级(AGP 9.0 release notes)——只要升 AGP 9.0,KSP2 就到了。你需要主动做的是处理器侧:确认 Room、Hilt 等处理器版本配套,把残余 kapt 清掉。

remote build cache 和 configuration cache 是一回事吗? 不是,别混着配。configuration cache 缓存”配置阶段的结果”,收益是跳过配置;build cache 缓存”任务的输出”,收益是跳过任务执行。前者对配置重的多模块项目收益大,后者对”很多人在相似代码上反复构建”的 CI 场景收益大。Gradle 9 上前者默认开启,两者在 CI 还要叠加 setup-gradle 的 User Home 缓存——三层各司其职。

没有自建 build cache 服务器,CI 还能快吗? 能先拿到大头:local build cache 加 setup-gradle 默认的 Gradle User Home 缓存,wrapper 与依赖下载直接命中,task 输出在同一 runner 的热缓存里复用。需要跨 runner 共享任务输出时再上 remote——Gradle 官方支持 HTTP 后端(HttpBuildCache),自托管或托管服务均可。先用 job summary 里的命中率报告说话,再决定要不要为 remote 服务器立项。

结语

从 2016 年系列里的 Gradle 2.x,到 2026 年默认开启 configuration cache 的 Gradle 9,这个话题十年的变化很有代表性:当年要解决的是”怎么把构建配置起来”,如今要防的是”升级会不会把构建弄死”。提速三件套——Configuration Cache、KSP2、构建扫描——在 2026 年的正确打开方式,是把它们当一组有依赖关系的工程任务,而不是三个独立开关:先测量(Build Analyzer 预检,Gradle Profiler 拿基线),再清 KAPT(在 Gradle 8.x 上完成),然后升 AGP 9.0 让 KSP2 与 config cache 默认就位,最后把 CI 的三层缓存配齐,用 job summary 的命中率持续盯梢。

下一步可做的事,按顺序:跑一次 --profile,看配置与执行的占比;在 Build Analyzer 里过一遍体检报告;给 gradle.properties 加上起步配置;挑一个模块把 kapt 换成 ksp;在 CI 的一个 job 上启用 setup-gradle,观察一周命中率。每一件半天内都能完成,叠起来的收益会用你自己的数字说话——这也是本文与清单式技巧文的区别:基线先立,优化才有对错。


相关阅读: AI 单元测试的有效性验证:用变异测试给 AI 生成的测试打分

参考资料

# 来源 说明
1 Gradle 9.0 release notes 2025-07-31;Configuration Cache 默认启用;Windows task 执行 5–10%;Java 24;逃生口
2 Gradle 9.0 configuration cache 文档 2025-07;”skip the configuration phase entirely”定性口径;要求 AGP 8.0+ 与全插件兼容;修复建议与 incompatibilities 章节
3 Gradle configuration cache requirements 配置输入跟踪;--configuration-cache-problems=report 诊断入口
4 Gradle roadmap “默认启用 Configuration Cache”状态 Shipped;2026-10-30 核对
5 Android — Optimize your build speed 8.1 stable 表述;配置输入跟踪;GC>15% 加堆(4/6/8 GB);Build Analyzer 预检;起步配置
6 AGP 8.1 release notes 2023-07;AGP fully supports configuration cache
7 AGP — Gradle 兼容矩阵 AGP 9.0 最低 Gradle 9.1.0;持续更新
8 AGP 9.0 release notes KGP 2.2.10 / KSP 2.2.10-2.0.2 自动升级;内置 Kotlin 支持;9.0.1 于 2026-01;9.0.0 精确日期未核实(约 2025 年末),待人工复核
9 AGP 9.5.0 release notes 2026;最低 Gradle 9.6.0、JDK 17、max API 37
10 Gradle 8.11 release notes 2024-Q4(精确日期未核实);并行任务调度重做;gradle init 新项目默认启用 Configuration Cache
11 Gradle 9.1 release notes 2025-11;Windows 默认 file system watching,构建延迟最高改善约 10%
12 JetBrains — Kotlin 2.2.0 Released 2025-06-23;KGP configuration cache 序列化提速最高 8%
13 InfoQ — Gradle 9 Released 2025-08;JetBrains 单场景 3.37s → 2.63s(量级参考)
14 Google — Migrate from kapt to KSP KAPT 两遍编译机理;KSP 最高 2 倍(up to 口径)
15 Android Developers 博客 — Accelerating Builds with KSP2 2024-12;Maps 增量 -15%、Play Store clean -22% / 增量 -24%;JS 渲染页面,数字经搜索摘要交叉验证,待人工复核
16 Medium — Accelerating Builds with KSP2 (preview) / Nia issue #369 2023-11;KSP1 vs KSP2 preview 基准;逐项百分比未核对,待人工复核
17 JetBrains — KSP 2.0.0 Released 2024-07;KAPT maintenance mode
18 google/ksp GitHub(含 issue #2394、issue #1805) KSP2 时间线与 opt-in 口径;kapt/ksp 混用 × configuration cache 失败
19 Kotlin KSP overview KSP2 架构:Kotlin Analysis API + K2 编译器前端
20 AndroidX Room releases Room 2.4.0 首次支持 KSP(实验,2022-01-27 stable);2.6.0 稳定支持(2023-10);2026-10-30 核对
21 Dagger releases / dagger.dev — KSP 指南 2.48 alpha KSP(2023-08-30,release notes 原文”alpha release”);stable 归属 2.60+ / KSP 2.3.9+(2.60 于 2026-06-26);日期经 GitHub Releases API 核对、stable 口径经 dagger.dev 核对(2026-10-30)
22 Gradle build cache 文档 local + remote 两级;relocatability 约束;命中率决定因素
23 gradle/actions setup-gradle 缓存内容与 cache key;cache-read-only;cache-encryption-key;job summary 报告
24 GitHub Actions 文档 每仓库 10GB 缓存配额
25 Gradle 客户案例 Curology 命中率 70–80%、9→4.5 min;Netflix 60%+;LinkedIn -40%;Charter -85%+;均为客户证言口径,渠道为域名级链接
26 Gradle build scans / performance 文档 Build Scan Performance 页能力;--profile 本地报告
27 Android — Build Analyzer 体检报告能力清单(daemon、GC、KSP 建议)
28 gradle/gradle-profiler A/B 基准、warm-ups/iterations、Chrome Trace / 火焰图
29 gradle.org — What’s new in Gradle 9 2025;Develocity 新增 CC miss 原因报告等(商业版能力)
30 Develocity — Gradle Configuration Cache(视频) / Fact or kapt?(视频) oEmbed 已验证存在;视频标题口径,不作数据引用
31 JetBrains — Kotlin 2.3.0 Released 2025-11;K2 推断/API 分析改进;Wasm 最高 2x、Native 最高 2.5x(与 Android JVM 构建无直接关系,仅生态节奏背景)