警惕!AGP 9.2 别只改版本号,R8 规则与构建链路全线收紧

前言

Google 发布了 Android Gradle Plugin 9.2.0

这一版不是大迁移,但它动到了几条构建主线:Gradle 版本要求抬到 9.4.1测试和覆盖率报告开始聚合R8 的 -keepattributes 规则更严格 ,以及 Lint / DSL / JDK 兼容问题修复

如果你的项目有多模块、CI 覆盖率、自定义 Lint、复杂混淆规则,升级 AGP 9.2 不能只看能不能编过。

先把构建环境对齐

AGP 9.2.0 的兼容矩阵已经变化。

bash 复制代码
AGP: 9.2.0
Gradle: 9.4.1
JDK: 17
SDK Build Tools: 36.0.0
默认 NDK: 28.2.13676358
最高支持 API: 36.1

升级入口通常先改插件版本:

bash 复制代码
plugins {
    id("com.android.application") version "9.2.0" apply false
    id("com.android.library") version "9.2.0" apply false
}

然后把 Gradle Wrapper 对齐到 9.4.1:

bash 复制代码
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip

JDK 还是 17。这个要求看起来稳定,但 CI 最容易在这里掉链子。

本地 Android Studio 可能已经用 JDK 17,CI 镜像却还停在旧版本;本地 Gradle Wrapper 已经更新,流水线缓存还在用老分发包。最后表现出来的不是业务编译错误,而是插件加载、同步、任务配置阶段失败。

统一测试报告来了

AGP 9.2.0 增加了一个实验能力:统一测试报告和覆盖率报告。

开启方式是在 gradle.properties 里加:

bash 复制代码
android.experimental.reportAggregationSupport=true

它解决的是多模块项目的老问题。

以前每个模块都有自己的测试报告:

bash 复制代码
app/build/reports/tests/
feature-login/build/reports/tests/
feature-device/build/reports/tests/
core/build/reports/tests/

覆盖率报告也类似。模块少的时候还能手动点开看;模块多了以后,CI 上很难快速回答三个问题:哪个模块挂了,哪个 variant 挂了,哪类测试挂了。

AGP 9.2 的方向是把不同模块、不同 variant、不同测试类型聚合到一个 HTML dashboard。

这个功能对单模块项目感知不强。对多模块 App、组件化工程、提测前全量测试和覆盖率归档更有用。

但它现在还是 experimental。更合适的接入方式是先放到非阻塞 CI 链路里验证,不要第一天就拿它做强制门禁。

R8 不再让通配符兜底

AGP 9.2 里最容易被忽略的是 R8 行为变化。

很多老项目都有类似规则:

bash 复制代码
-keepattributes *
-keepattributes *Annotation*
-keepattributes *Invisible*

这类规则写起来省事,但范围太宽。

AGP 9.2 之后,带通配符的 -keepattributes 不再匹配下面三类 runtime invisible annotation:

bash 复制代码
RuntimeInvisibleAnnotations
RuntimeInvisibleParameterAnnotations
RuntimeInvisibleTypeAnnotations

也就是说,下面这些规则不会再保留 runtime invisible annotation:

bash 复制代码
-keepattributes *
-keepattributes *Annotation*
-keepattributes *Invisible*

如果项目确实需要保留,需要显式写出属性名:

bash 复制代码
-keepattributes RuntimeInvisibleAnnotations,
                RuntimeInvisibleParameterAnnotations,
                RuntimeInvisibleTypeAnnotations

这个变化是为了让 R8 更贴近 D8 的行为。runtime invisible annotation 本来不能在运行时读取,D8 通常会移除它们;R8 过去为了兼容 ProGuard 保留了更宽松的匹配方式。

普通业务 App 多数不会感知。

但如果项目里有字节码扫描、AOP、插件化、注解元信息分析,或者历史混淆规则里大量使用宽泛 -keepattributes,升级后要重点跑 release 包验证。

只跑 assembleDebug 不够。这里影响的是 shrink / optimize / obfuscate 后的产物。

member rule 支持排除名称

R8 这次还扩展了配置语言。

member rule 现在支持 negated name pattern,也就是可以匹配"不符合某个名称模式"的成员。

官方给的例子是:匹配所有不以 ForTesting 结尾的方法。

bash 复制代码
-keepclassmembers class com.example.MyClass {
  *** !*ForTesting(...);
}

这个能力适合收窄 keep 规则。

以前很多规则只能正向匹配,写到最后容易变成"先全保住再说"。现在可以在成员规则里直接表达排除条件,规则可以更接近真实意图。

它也有边界:如果反向成员名模式里包含通配符,这些通配符不能在 -if 后续规则里反向引用。

简单说,可以用它减少过宽规则,不要拿它写复杂模板。

修复项更偏工程链路

AGP 9.2.0 的修复项主要集中在 alpha 阶段,方向比较工程化。

APK 重命名相关问题被修复。使用新 AGP DSL 改 APK 输出名的项目,可以关注这条。

bootClasspath 访问时报 targetCompatibility is not yet finalized 的问题也修了。这类问题常见于自定义 Gradle 插件或构建逻辑访问 Android 配置太早。

JDK 26 下的 JdkImageTransform failure 被修复。大多数项目短期内不会把 CI 切到 JDK 26,但这说明 AGP 还在继续处理新 JDK 的兼容问题。

Lint 相关修复更多:

bash 复制代码
SARIF 报告上下文截断
Lint Gradle client 可靠性问题
Lint Gradle task 忽略 --quiet
自定义 Lint 使用 Java 21 bytecode 失败
Lint 文案错误

如果项目只是普通业务 App,这些修复不一定有感知。

如果你们接了自定义 Lint、SARIF 上报、CI 静态扫描,这些修复会更实际。

升级验证别只跑 debug

AGP 升级最容易漏掉 release 链路。

最低限度要跑一次 release 构建:

bash 复制代码
./gradlew assembleRelease

多 flavor 项目不要只跑默认 variant。至少要覆盖线上会发版的 flavor 和 buildType。

如果有自定义 Lint,单独跑:

bash 复制代码
./gradlew lint

如果有多模块测试,可以先在分支里打开聚合报告:

bash 复制代码
android.experimental.reportAggregationSupport=true

最后看 R8 规则。重点搜这几类:

bash 复制代码
-keepattributes *
-keepattributes *Annotation*
-keepattributes *Invisible*

如果项目不依赖 runtime invisible annotation,不要为了保险继续写宽规则。

如果确实依赖,就改成显式属性名,并把对应场景放进 release 包回归。

最后

AGP 9.2.0 不是大版本迁移,但它碰到了构建系统里几个容易被忽略的位置。

小项目可以等 Android Studio、Gradle、CI 环境统一后再升。

多模块项目、自定义 Lint 项目、R8 规则复杂的项目,建议单独拉分支验证。重点不是"能不能编过",而是 release 包、测试报告、混淆产物和 CI 链路是否都正常。

#Android #AGP #Gradle #R8 #AndroidStudio

相关推荐
千里马学框架20 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台20 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone21 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc21 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone1 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen1 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone1 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui