R8类型安全Keep规则与DEX优化实战

Google Play 将 DEX 优化设为硬门槛,R8 工具链助应用达标。
Google Play 已要求 DEX 的 shrinking、optimization 和 obfuscation 均达到 25% 以上,否则可能影响应用可见性。文章指出,宽泛的 keep 规则是优化不足的主因,尤其源于反射和库的 consumer rules。为此,Google 推出 R8 配置分析器、Jetpack Keep 和 Android CLI analyze 三项工具:分析器可视化规则影响,Jetpack Keep 从反射代码自动生成类型安全窄规则,CLI 用与 Play 相同逻辑本地校验。Grab、Whoop 等案例证明,结合 baseline profiles 可显著降低 ANR、提升启动速度。团队建议按“分析-生成-校验”路径持续治理。
Google Play 对 DEX 优化的要求已经从「锦上添花」变成了「硬性门槛」。在硬件供应紧张、设备内存受限的大背景下,一个经过充分优化的 DEX 直接决定应用能否更省内存、启动更快、减少 ANR。更现实的是,Google Play 已宣布新的应用质量要求,其中 DEX 代码优化(shrinking、optimization、obfuscation)需要达到 25% 以上,未达标的应用可能影响在 Play Store 的可见性和发布能力。据 Android DevRel 团队的 Brianna 与 Performance 团队的 Chris Krieg 在技术分享中介绍,目前仍有 41% 的头部应用低于 25% 的优化门槛,但同时有 13% 的头部应用达到了该门槛的三倍。

为什么 DEX 优化被重新重视
优化带来的收益有实际数据支撑。Grab 在采用 R8 full mode 并精炼 keep 规则后,实现了 78% 优化、79% shrinking 和 82% obfuscation;结合 baseline profiles,ANR 降低了 32%,启动速度提升了 35%。头部应用首次启用 R8 时,平均 DEX 体积下降 38%,用户感知 ANR 下降 16%。已经使用 R8 的应用若进一步把优化、收缩、混淆水平提升到 50% 以上,平均还能再获得 25% 的 DEX 体积下降、4% 的启动时间下降和额外 17% 的用户感知 ANR 下降。
这些数字说明,R8 不是「配一次就忘」的选项,而是需要持续治理的工程实践。历史上,反射调用让输入不可预测,容易导致运行时崩溃,于是应用团队和库团队倾向于添加宽泛的 keep 规则「保平安」。这类规则一旦积累,就会像滚雪球一样拖累整个应用的优化空间。
R8 full mode 是 R8 的一种更激进的优化模式。与默认的兼容模式不同,full mode 假设所有代码都遵循标准的 Java/Kotlin 语义,从而启用更全面的类合并、方法内联和成员重写。这能显著提升优化与混淆比例,但也会暴露原本被宽松规则掩盖的反射或动态调用问题。因此,启用 full mode 通常需要配合更精确的 keep 规则,并经过充分测试。Grab 的实践表明,在处理好反射和依赖注入等场景后,full mode 带来的 ANR 与启动收益非常可观。
从宽泛通配符到类型安全注解
问题根源在于反射。Chris 用一个对象实例化函数举例:通过字符串引用类名进行反射创建对象,R8 在静态分析时无法看到这层关系,只能靠 keep 规则兜底。理想情况下应尽量避免反射,尤其在当前已有成熟的序列化和依赖注入代码生成工具,但可选依赖、动态实例化子类、序列化等场景仍让反射难以完全消失。
过去写一条「理想」的 keep 规则非常繁琐:要区分 Kotlin 类、要覆盖子类、要限定构造函数、要允许访问修改以不阻碍后续优化,最后还要用条件判断让规则只在真正调用反射时才生效。几乎没有人会完整做到这些。手动写窄规则难读难维护,@Keep 注解又过于僵硬、不支持调用点分析。

Jetpack Keep 的思路是把 keep 规则「贴」在反射代码旁边。它由 Gradle 插件和注解库组成,在构建时通过 lint 分析方法内的所有反射行为,自动生成注解,再由注解生成 keep 规则。这条规则针对具体子类、条件化于反射调用点、并尽可能允许后续优化——正是过去那条「理想规则」,但不再需要人工维护。对于类不在 classpath 上的可选依赖场景,仍可用字符串引用类名,参数类型则用类引用保证安全。
Jetpack Keep 要求 AGP 8.7,可应用于应用、Android 库、AAR、KMP 库和 jar。它的关键设计是:即使消费方使用老版本 R8 或第三方工具,库仍会导出标准 consumer rules,不会引入不兼容格式。
Keep 规则(ProGuard/R8 规则)用于告诉优化器哪些类、方法或字段不能被移除或重命名。一条规则通常由类名匹配、成员匹配和修饰符选项组成,例如 -keep class com.example.** { *; } 会保留整个包下的所有成员。规则越宽泛,R8 可优化的范围就越小;越精确,优化效果越好但维护成本越高。反射、JNI、序列化等动态访问是 keep 规则的主要来源。现代工具如 Jetpack Keep 的目标就是根据实际反射调用点自动生成最小必要的规则,替代人工编写的宽泛通配符。
用分析工具定位「肥胖」规则
R8 配置分析器是排查 DEX 优化的起点。它生成 HTML 报告,量化 shrinking、optimization 和 obfuscation 三个维度,并列出 keep 规则分析表,可点进每条规则查看它具体保留了多少类、方法和字段。报告还会标出被更宽规则覆盖的 subsumed rules 和可安全删除的 unused rules。需要注意,分析器在最终优化和 DEX 编译前计算分数,因此数值不会与 Play Console 完全一致,但适合在本地快速验证优化潜力。
据分享中的案例,Whoop 团队运行分析器后发现 shrinking 和 obfuscation 都是 74%,但 optimization 为 0。进一步排查发现构建使用了一个禁用优化的旧 ProGuard 文件,切换后优化达到 55%,APK 体积减少 4%;结合 baseline profiles,冷启动提升 38%,过度冻结帧减少 28%。
Brianna 还介绍了 R8 analyzer skill:向 agent 发出「分析我的 R8 配置」的请求,工具不仅生成报告,还会指出影响最大的规则。例如它会说明某条包级 keep 规则阻止了 22% 的代码被优化,并建议收窄该规则。

Baseline profiles 是随应用一起分发的配置文件,记录了应用关键用户路径上需要提前编译的方法列表。Android 运行时在安装或后台维护时据此进行 AOT 编译,从而减少解释执行和 JIT 开销。它本身不改变 DEX 优化比例,但能与 R8 的代码收缩和优化形成互补:R8 减小代码体积,baseline profiles 让剩余关键代码更快执行。Grab 和 Whoop 的案例中,baseline profiles 与 R8 配合后才实现了显著的 ANR 和启动时间下降。
库的 keep 规则问题与 CLI 校验
库生态是重灾区。许多库以稳定性为名附带宽泛规则,或在文档中让应用开发者自行添加。分享中提到,Google 自己的 SDK 也未能幸免,过去一年已有超过十几个 Google 库修复了过宽的 keep 规则。一条包级通配规则会让整个库的所有类都被视为入口点,R8 无法将其判定为死代码,优化空间被严重挤压。
Android CLI 的 analyze 命令使用与 Play Store 完全相同的逻辑,可在本地直接分析 bundle,给出与 Play 一致的 DEX 体积和优化百分比,并支持 JSON 输出以便脚本化回归测试。它也能分析 AAR 库,标记高 keep 比例、宽泛规则以及「没有指向任何目标」的危险规则——后者往往意味着它以无界方式影响其他代码。

团队建议的处理顺序是:先尝试升级有问题的库;若仍存在问题,向库开发者提交 issue 并附上 analyze 报告,用数据说明「你保留得太多,请帮我优化应用」。此外,新的应用模板已包含 package scope,AGP 9.2 让协程原语速度提升两倍,Tinder 在升级后 ANR 下降 13%;AGP 9.3 则带来重新设计的 R8 API、更清晰的默认规则以及 keep 规则的源码目录支持。
总结来看,DEX 优化是一条可复制的路径:用 R8 配置分析器或 analyzer skill 找到问题规则,用 Jetpack Keep 从反射代码自动生成类型安全规则,最后用 Android CLI 在发布前做本地校验。三者结合,才能在不牺牲稳定性的前提下把优化水平推过门槛。
AAR 库 是 Android 的二进制库分发格式,除了编译后的代码和资源,还可以携带 consumer-rules.pro 等消费者规则文件。这些规则会在应用构建时自动合并进最终的 R8 配置。如果库作者在 consumer rules 中写入包级通配规则,所有使用该库的应用都会被迫保留大量无用代码,且应用开发者往往难以察觉。因此,分析 AAR 的 keep 规则比例、识别无界规则,是治理 DEX 优化的重要环节。
相关推荐

合理使用制度为何对AI时代人人有益
从Hacker News讨论出发,解析合理使用(Fair Use)原则在AI训练与内容创作中的法律逻辑、争议焦点及其对创作者与技术生态的双重影响。

Salesforce 3.75亿美元收购Rune,AI物流技术补强国防业务
Salesforce 据报道以 3.75 亿美元收购国防科技初创公司 Rune,这家 AI 物流公司的技术将用于补强 Salesforce 的 Missionforce 国防平台,也延续了 Salesforce 近期的并购节奏。

Mistral Large 4开源万亿参数,微软6万员工自愿离职
Mistral Large 4 开源万亿参数多模态模型,编码智能体评测得分 48;闪迪财报显示 AI 推理重塑 NAND 需求;谷歌 Gemini 上线应用内文件编辑,OpenAI 上调 Codex 额度,微软向 6 万员工提供自愿离职方案。