如果你的 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)试迁移,验证构建产物
3.迁移核心库:Room → Hilt → 其余
按影响范围由小到大,每步都做完整回归测试。注意 Room schema 路径配置变更
4.彻底移除 KAPT 插件
所有处理器迁移完成后,从 plugins{} 移除 kotlin-kapt,清理残留 kapt{} 块
5.度量与优化
用 --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 & 大前端工程化