4. AGP 7.x 到 8.x 的亮点:命名空间强制、变体感知、KSP 支持
AGP 8.x 发布时,说实话我是捏了把汗的。毕竟 7.x 我已经用得很顺手了,突然要我改一堆配置,谁都不太情愿。但真正迁移之后,我发现这几个变化确实值回票价。今天我就把我踩过的坑和数据摆出来,告诉你为什么该升级。
4.1 命名空间强制:终于不用再写 package 了
以前我们在 AndroidManifest.xml 里写 package="com.example.app",然后在 build.gradle 里又写一遍 namespace,经常搞混。AGP 8.x 直接强制要求:AndroidManifest.xml 里的 package 必须去掉,全部移到 build.gradle 的 namespace 里。
为什么会这样?因为 Google 发现两处定义很容易冲突,尤其是多模块项目里,经常有人只改了其中一个,导致构建失败。
- AndroidManifest.xml 不再使用
package属性 - 所有模块的
build.gradle必须显式声明namespace - R 类的生成路径完全由
namespace决定
我记得第一次迁移 8.x 时,有个老项目里有几十个模块,我写了个脚本批量替换。结果有个模块忘了加 namespace,编译直接报错。后来我查了文档才知道,AGP 8.0 之后 AndroidManifest.xml 里的 package 会被忽略,如果你没设置 namespace,构建就失败。
避坑指南: 我曾经在合并 AndroidManifest.xml 时遇到过 tools:replace="android:authorities" 失效的问题,原因就是 namespace 没写对。建议每个模块的 namespace 都跟模块的包名保持一致,不要随意改。
// build.gradle.kts (模块级)
android {
namespace = "com.example.app.feature.login"
compileSdk = 34
// ...
}
4.2 变体感知:构建速度提升 10%~30%
AGP 7.x 里,每次运行 ./gradlew assembleDebug 都会把所有的 flavor 和 buildType 组合都过一遍,即使你只想要一个变体。8.x 引入了“变体感知”(Variant Aware)特性,它只构建你当前需要的变体,其他变体直接跳过。
你想想看,如果一个项目有 4 个 flavor 和 2 个 buildType,那就是 8 个变体。以前每个变体都要做资源合并、AAPT2 处理、Dex 等等。现在只做你指定的那个,速度能不快吗?
debug 构建从 2 分 15 秒降到了 1 分 40 秒,提升了约 26%。
增量构建更是夸张,从 45 秒降到 20 秒以内。
另外,AGP 8.x 还优化了任务图,很多不必要的任务直接跳过。比如你只改了 Java 代码,资源相关的任务就不会再跑。
| 对比项 | AGP 7.x | AGP 8.x |
|---|---|---|
| 变体构建策略 | 全部构建再过滤 | 按需构建 |
| 增量构建 | 任务粒度较粗 | 更细粒度的缓存 |
| 全量构建时间(4 flavor) | ~135s | ~100s |
| 增量构建时间 | ~45s | ~20s |
我个人习惯把 flavor 分得很细,比如 dev、staging、production,每种还有不同的后端地址。以前每次改完代码都要等很久,现在用 AGP 8.x 后,切换 flavor 几乎感觉不到额外开销。不过要注意,变体感知依赖 Gradle 配置缓存(Configuration Cache),需要先开启这个特性。
// gradle.properties
org.gradle.configuration-cache=true
4.3 KSP 支持:告别 kapt 的慢和 Java 编译
KSP(Kotlin Symbol Processing)是 AGP 8.0 开始官方推荐替代 kapt 的注解处理器方案。它的核心优势是直接分析 Kotlin 源码符号,不需要把 Kotlin 编译成 Java 存根,所以速度能快 2~3 倍。
我在项目中遇到过 Room 和 Glide 的注解处理。以前用 kapt 时,全量构建需要 40 多秒,换成 KSP 后直接降到 12 秒。说白了,kapt 为了兼容 Java 注解处理器做了很多无用功,而 KSP 是 Kotlin 原生方案,效率高太多了。
迁移示例(以 Room 为例):
// AGP 7.x (kapt)
plugins {
id 'kotlin-kapt'
}
dependencies {
kapt "androidx.room:room-compiler:2.6.1"
}
// AGP 8.x (KSP)
plugins {
id 'com.google.devtools.ksp' version '1.9.22-1.0.17'
}
dependencies {
ksp "androidx.room:room-compiler:2.6.1"
}
不过要注意,不是所有库都支持 KSP。比如一些老旧的库只提供了 kapt 适配器。我的经验是:先查官方文档看是否支持 KSP,如果不支持可以先用 kapt 过渡,但尽量推动第三方库升级。
- 速度:KSP 快 2~3 倍
- 增量编译:KSP 支持更好
- 内存占用:KSP 更低
- 兼容性:KSP 仅 Kotlin,kapt 兼容 Java
嗯,这里还要提一点:KSP 与 Gradle 配置缓存配合得非常好,不会像 kapt 那样经常触发重建。我个人建议,只要你的项目是纯 Kotlin 或者大部分是 Kotlin,就立刻切换到 KSP。如果你的项目还有大量 Java 代码,可以等后续版本再迁移。
4.4 迁移建议与总结
这三个亮点其实是环环相扣的:命名空间强制规范了配置,变体感知减少了无用功,KSP 提升了注解处理效率。但迁移时千万别一股脑全上,我的建议是分三步走:
- 先升级 AGP 8.x 并处理 namespace——这一步相对简单,用 IDE 的自动迁移工具就行。
- 开启配置缓存和变体感知——观察一周,确认没有任务异常。
- 逐个迁移注解处理器到 KSP——从 Room 开始,再到 Glide、Moshi 等,每迁移一个做一次回归测试。
升级到 AGP 8.x 后,发现某个自定义 transform 彻底不能用了(AGP 8.0 移除了 Transform API)。如果你项目里还有这类旧插件,必须先替换到
AsmClassVisitorFactory 或直接移除。否则构建会直接报错,而且错误信息不太友好。
总的来说,AGP 8.x 的这三个改进都是实打实的性能优化。迁移成本其实不高,收益却很显著。如果你还没动手,我推荐你从下周一开始试点,先挑一个小模块做灰度测试。等跑顺了再全量推广,你会发现构建居然能快到这种程度。