告别 KAPT,拥抱 KSP:一次工具链迁移让构建提速 40%
如果你的 Android 项目还在用 KAPT,每次./gradlew build都要盯着进度条发呆——这篇文章你应该看完。
Moshi 2.0 alpha 刚宣布彻底放弃 KAPT,Kotlin 2.3.20 把 KSP 推上了新的成熟度,Hilt、Room、Retrofit 的 KSP 适配也早已 stable。这一波工具链升级的时机已经到了。
这篇文章不讲原理,只讲迁移路径、踩坑记录和实测收益。
① 为什么 KAPT 已经是瓶颈
KAPT(Kotlin Annotation Processing Tool)在 2017 年诞生时是一个"临时方案"——把 Java APT 的接口桥接到 Kotlin,代价是每次注解处理都要先把 Kotlin 代码编译成 Java stub,再交给注解处理器。
这个 stub 生成过程是串行的、不可并行的,而且无法增量。也就是说:
改一行代码 → 全量重新生成 stub → 注解处理器全量重跑
多个 KAPT 处理器顺序执行,无法并行
构建缓存(Gradle Build Cache)命中率低,CI 加速效果差
在中大型项目中,KAPT 相关任务往往占据30-50% 的全量构建时间。Room 的 DAO 处理、Hilt 的依赖注入代码生成、Moshi/Gson 的适配器……每一个都是 KAPT 任务,叠加起来非常可观。
② KSP 的核心差异
KSP(Kotlin Symbol Processing)是 JetBrains 2021 年推出的正式替代方案。它直接在 Kotlin 编译器的 AST(抽象语法树)层面工作,跳过了 Java stub 生成。
打个比方:KAPT 就像你每次改一张 PPT,都要先把它打印成纸质版、让别人手抄一遍再处理,然后你才能拿到结果。KSP 直接在原文件上批注,中间那道多余的"打印 → 手抄"流程消失了。更形象地说,KAPT 是用了九年的 USB-A 转接头——凑合能用,但原生接口早就该上了。
Kotlin 源文件
↓
KAPT 路径(旧):
Kotlin →Java Stub 生成(串行,耗时)→ Java APT 处理 → 生成代码
KSP 路径(新):
Kotlin →直接读取 KSP API(增量,可并行)→ 生成代码
↓
编译产物
关键收益对比:
| 维度 | KAPT | KSP |
|---|---|---|
| 增量编译 | ❌ 不支持 | ✅ 支持 |
| 并行处理 | ❌ 串行 | ✅ 多处理器并行 |
| Java 互操作 | ✅ 原生支持 | ⚠️ 有限支持 |
| Build Cache 友好度 | 低 | 高 |
| Kotlin Multiplatform | ❌ 不支持 | ✅ 原生支持 |
③ 迁移实战:主流库的 KSP 配置
以下是当前(2026年初)主流库的 KSP 迁移状态和配置:
3.1 Hilt(依赖注入)
Hilt KSP 支持已 stable(hilt-android 2.51+),迁移步骤:
// build.gradle.kts (root) plugins { id("com.google.devtools.ksp") version "2.0.21-1.0.28" apply false } // app/build.gradle.kts plugins { // 移除 KAPT // id("kotlin-kapt") id("com.google.devtools.ksp") id("com.google.dagger.hilt.android") } dependencies { implementation("com.google.dagger:hilt-android:2.51.1") // kapt("com.google.dagger:hilt-compiler:...") → 改为: ksp("com.google.dagger:hilt-compiler:2.51.1") }3.2 Room(本地数据库)
Room 2.6.0+ 正式支持 KSP,需注意room.schemaLocation配置方式有变化:
dependencies { implementation("androidx.room:room-runtime:2.6.1") ksp("androidx.room:room-compiler:2.6.1") } // 旧 KAPT 配置 // kapt { // arguments { arg("room.schemaLocation", "$projectDir/schemas") } // } // KSP 新配置方式 ksp { arg("room.schemaLocation", "$projectDir/schemas") arg("room.incremental", "true") // 启用增量处理 }3.3 Moshi(JSON 序列化)
随着 Moshi 2.0 alpha 完全抛弃 KAPT,生产版本(1.15.x)也已支持 KSP,且从 KAPT 迁移时无需修改业务代码:
// 移除旧的 KAPT 处理器 // kapt("com.squareup.moshi:moshi-kotlin-codegen:1.15.1") // 添加 KSP 处理器 ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.1")④ K2 编译器:构建加速的另一个杠杆
Kotlin 2.3.20 里,K2 编译器已完全稳定。如果你的项目还没开启,这是迁移 KSP 后的下一个优化点。
K2 的核心优化是前端编译器重写——类型检查、符号解析、控制流分析都做了算法级优化。JetBrains 官方数据:K2 在大型项目的全量构建中比 K1 快15-30%,增量编译快20-40%。
说句直话:如果你的 CI 构建超过 10 分钟还没迁 KSP、没开 K2,这不是技术债,是管理失职。工具已经成熟,迁移成本极低,继续拖下去的唯一理由就是"优先级排不上"——而这个借口在每天浪费几十人次构建等待时间的背景下,说不过去。
开启方式极简:
// gradle.properties kotlin.jvm.target.validation.mode=warning // K2 编译器在 Kotlin 2.0+ 默认开启,确认版本即可 // 验证当前编译器版本 // ./gradlew :app:compileDebugKotlin --info | grep "Using Kotlin"需要关注的兼容性问题:
部分 Kotlin 编译器插件(如 Parcelize、Serialization)需确认版本与 K2 对齐
如果用到了某些依赖反射行为的库,需测试回归
Compose Compiler 2.0+ 原生支持 K2,更新即可
⑤ Monorepo 下的工具链运维:几个关键配置
在多模块/Monorepo 项目中,KSP 的配置有一些额外注意点。
5.1 Convention Plugins 统一 KSP 版本
多模块项目最怕的是各模块自己维护处理器版本,导致版本漂移和构建缓存失效。推荐用buildSrc或 Composite Build 的 Convention Plugin 统一管理:
// buildSrc/src/main/kotlin/android-ksp-convention.gradle.kts plugins { id("com.google.devtools.ksp") } // 统一的 KSP 参数配置 ksp { arg("correctErrorTypes", "true") } // 各业务模块只需 plugins { id("android-ksp-convention") }5.2 CI 构建优化:利用 KSP 增量提速
KSP 的增量处理配合 Gradle Build Cache 可以显著减少 CI 时间。典型 pipeline 配置:
代码提交
↓
Gradle Build Cache 恢复
↓
KSP 增量处理(仅变更文件)
↓
并行任务:
分支A→ 单元测试
分支B→ Lint 检查 + APK 编译
↓
产物归档 + Cache 写回
关键gradle.properties配置:
org.gradle.caching=true org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC ksp.incremental=true ksp.incremental.log=false⑥ 迁移路线图:分阶段推进,风险可控
- 升级 Kotlin 到 2.0+(先决条件)
确保 Kotlin 版本 ≥ 2.0,AGP 版本 ≥ 8.0,K2 编译器默认生效
- 新增 KSP 插件,先并行运行
同时保留 KAPT,只对 1-2 个影响小的库(如 Moshi)试迁移,验证构建产物
- 迁移核心库:Room → Hilt → 其余
按影响范围由小到大,每步都做完整回归测试。注意 Room schema 路径配置变更
- 彻底移除 KAPT 插件
所有处理器迁移完成后,从 plugins{} 移除kotlin-kapt,清理残留 kapt{} 块
- 度量与优化
用--scan或 Gradle Build Scan 对比迁移前后的构建时间分布,量化收益
⑦ 实测:迁移后能快多少
根据社区和官方数据汇总(不同项目差异较大):
| 场景 | KAPT | KSP + K2 | 提升 |
|---|---|---|---|
| 中型项目全量构建 | 4m 20s | 2m 45s | -37% |
| 增量构建(改 DAO) | 58s | 19s | -67% |
| CI 流水线时间 | 12m | 7m 30s | -38% |
增量构建的提升尤其明显——这也是日常开发体验改善最直接的地方。改一个 Room DAO,原来等将近一分钟,迁移后不到 20 秒,每天节省的时间累计起来相当可观。
小结
KAPT → KSP 这条迁移路径,技术上已经非常成熟:主流库全部支持,迁移成本极低,收益明显且可量化。
给一个明确的时间判断:2026 Q3 是最后的窗口。Kotlin 2.x 后续路线图中,KAPT 兼容层已进入"维护态",不排除在某个大版本中正式移除。到那时你是被动升级(踩坑)还是主动收益(早早验收),现在就能决定。
配合 K2 编译器,改几行配置,构建时间可能直接少掉三分之一。这是投入产出比最高的一类工程化升级——不需要重构业务代码,不需要评审,不需要排期,只需要工程师花半天时间跑一遍迁移流程。
工程化的价值往往就藏在这些"不起眼的工具升级"里。你不会记得哪次等构建的 58 秒,但那些秒数乘以团队人数、乘以每天构建次数,就是每个月实实在在消失的几十个工时。
— END —
关注公众号,持续追踪 Android & 大前端工程化
