默认情况下,R8 会进行大量优化来提升性能和大小,但这些优化可能不会立即应用于您的应用。如果您是首次在大型应用中启用 R8(或启用完整模式),请尝试逐步采用优化措施:暂时关闭混淆功能,并一次为部分代码启用 R8,而不是为应用中的所有代码启用。我们建议您在本地开发期间采用这种增量方法,但您也可以在内部质量检查测试期间或甚至在正式版中采用这种方法,以逐步进行部署。您要采取的确切步骤取决于您希望的发布时间表以及您对预发布测试覆盖率的信心。
限制优化
R8 会执行多种类型的优化,包括移除代码、重写代码和移除资源。下面简要介绍了优化类型:
- 代码缩减(或摇树优化):移除未引用的代码
- 混淆处理(或标识符缩减):缩短类和方法的名称
- 优化:重写代码,例如内嵌
为降低出错几率,您可以先只启用其中的部分优化。
仅启用树摇动
代码缩减(也称为“摇树优化”)会移除似乎未引用的代码。我们建议您先从树摇动开始,因为它是最简单的。
如需仅启用树摇动功能,请将以下代码添加到 proguard-rules.pro
文件中,以关闭其他类型的优化。关闭混淆功能至关重要,因为这样可以让堆栈轨迹更易于阅读。
-dontobfuscate // Use temporarily to turn off identifier minification
-dontoptimize // Use temporarily to turn off optimization
最终,您不希望发布此配置,因为它会严重限制 R8 优化代码的能力,但在首次在存在问题且需要修复的大型代码库中采用 R8 时,它是一个很好的起点。
使用兼容模式
默认情况下,R8 会以完整模式运行。完整模式可显著提升性能并缩减大小,但在首次启用缩减功能时,您可以暂时停用该模式,改用兼容模式。
如需使用兼容模式,请在 gradle.properties
文件中使用以下设置:
android.enableR8.fullMode = false // Use temporarily to disable full mode
启用其余优化
确认树摇动功能适用于您的应用后,您可以移除上述设置,以重新启用混淆、优化和 R8 完整模式。请注意,混淆处理可能会使调试变得更加困难,因此我们建议先解决树摇动问题。
如需详细了解如何对堆栈轨迹进行去混淆处理,请参阅恢复原始堆栈轨迹。
限制优化范围
完全优化的 build 会优化每个库和软件包中的所有代码,因此,首次启用 R8 时遇到问题很常见。如果您发现应用的某个部分存在优化问题,请勿完全关闭 R8,否则您将无法在其他任何地方获得优化带来的好处。相反,请仅在导致问题的应用部分暂时停用 R8。
使用软件包级 keep 规则
我们建议您使用软件包级保留规则,在应用的某些部分暂时停用 R8。您应始终在日后返回来解决这些优化问题;这通常是一种权宜解决方案,用于解决问题区域。
例如,如果应用的某个部分大量使用 Gson 并导致优化问题,理想的解决方法是添加更多有针对性的 keep 规则或改用 codegen 解决方案。不过,为了解除优化应用其余部分的限制,您可以将定义 Gson 类型的代码放置在专用子软件包中,并向 proguard-rules.pro
文件添加如下规则:
-keep class com.myapp.json.** { *; }
如果您使用的某个库对内部组件进行了反射,您也可以同样为整个库添加 keep 规则。您需要检查库的代码或 JAR/AAR,以找到要保留的适当软件包。再次提醒,我们不建议长期保留此设置,但它可以解除对应用其余部分的优化限制:
-keep class com.somelibrary.** { *; }
移除软件包级保留规则
当应用在使用软件包级保留规则后正常运行后,您应返回并添加有针对性地保留规则,或移除最初需要保留规则的反射用法或库。
例如,在 AndroidX 中,为了仅保留相关类,保留扩展特定类的所有规则非常常见。通常,反射应仅定位到扩展特定抽象类、实现特定接口或具有特定运行时注解的类或方法。以上每种方式都是定义保留规则的受支持方式,这样您就不必在最终的完全优化应用中添加软件包级保留规则。