使用 R8 配置分析器

R8 配置分析器是一款旨在帮助您最大限度提高 R8 性能优势的工具,它可提供有关应用配置质量的详细数据分析。通过监控关键指标(尤其是压缩、优化和混淆得分),您可以跟踪和改进 R8 优化,这些指标表示可用于优化的代码库百分比。通过识别广泛或不必要的保留规则(包括第三方库引入的保留规则),分析器可帮助您优化配置,确保 R8 能够尽可能有效地优化您的类、字段和方法。

生成报告

使用 AGP 9.3.0 及更高版本时,您可以使用专用独立 Gradle 任务或在 R8 构建期间自动生成 R8 配置分析器报告。

运行独立的 Gradle 任务(建议在本地使用)

在积极迭代保留规则时,请使用独立的 Gradle 任务快速评估更改的影响,而无需完全构建 APK 或 Bundle:

./gradlew :app:analyzeReleaseR8Config

由于此任务会跳过 APK 或 Bundle 生成,因此反馈环会短得多。这样一来,您就可以快速分析保留规则对缩小、优化和混淆得分的影响,并立即对其进行优化。HTML 报告生成于 app/build/reports/r8/r8-config-analyzer-release.html

在常规 build 期间自动生成

运行完整的 R8 发布版本 build(例如 assembleRelease)时,系统会在 build/outputs/mapping/release/configanalyzer.html 自动生成报告。 如需在常规 build 期间停用输出的自动生成功能,请设置以下 Gradle 属性:

android.experimental.r8.enableR8ConfigurationAnalyzer=false

对于 AGP 9.2 及更低版本

对于 AGP 9.2 及更低版本,在运行启用了 R8 的 build 的 Gradle 任务时,请设置 com.android.tools.r8.dumpkeepradiushtmltodirectory 系统属性。

./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=<output_directory>

例如,使用以下命令在 /tmp/r8analysis 目录中生成 HTML 报告:

# To create the /tmp/r8analysis folder.
mkdir -p /tmp/r8analysis

# To generate the report in the /tmp/r8analysis folder.
./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=/tmp/r8analysis

了解报告

R8 配置分析器可深入了解应用的 R8 配置以及每条保留规则对应用的影响。这有助于您从 R8 中获得最大程度的优化,从而提升应用性能。您可以使用以下得分来了解 R8 可优化多少代码库。

报告摘要部分示例
图 1. 报告摘要部分示例。

缩减得分

当 R8 缩减应用时,它会识别并消除未使用的代码和资源,从而减小应用的总体大小,确保最终 build 尽可能精简。缩减得分用于跟踪可缩减的类、字段和方法的百分比。例如,如果缩减得分为 66%,则表示 R8 可以对 66% 的代码库执行缩减。

优化得分

R8 会执行方法内联和类合并等优化,从而提升应用的启动速度并改善内存使用情况。优化得分会跟踪接受 R8 优化的类、字段和方法的百分比。例如,如果优化得分为 66%,则表示 R8 只能在 66% 的代码库中执行优化。

混淆得分

通过将类、字段和方法混淆为较短的名称,R8 可减少应用的元数据占用空间,从而节省内存。混淆得分用于衡量代码库中可进行混淆的代码所占的百分比。

优化保留规则

为了提高得分并解锁更好的 R8 优化,您应优化 keep 规则,使其不会不必要地阻止 R8 优化您的应用。您应仅保留使用反射访问的类、方法或字段。

如需实现此目的,请使用保留规则分析

保留规则分析示例
图 2. 保留规则分析示例。

如需查看规则的详细分析,请点击相应规则以打开详情界面。

保留规则分析示例
图 3. 保留规则分析示例。

如何优化保留规则

如需优化保留规则并充分发挥 R8 优化对应用的潜力,请执行以下操作:

  1. 在配置分析器中,查看每条保留规则中无法被 R8 优化的类、字段和方法的百分比。使用此功能可识别大量类、字段或方法中阻止优化的 keep 规则。系统还会列出每条保留规则所阻止的优化属性。
  2. 如果您发现某条保留规则阻止了大量类的优化,则应务必检查该保留规则阻止优化的类、字段和方法,看看该规则是否保留了未使用反射动态调用的项。
  3. 通过选择合适的 keep 选项遵循最佳实践,仅定位必要的类、字段或方法,从而减少因 keep 规则而受阻的优化。
  4. 调查并运行测试,以涵盖 keep 规则中受影响的类、字段和方法,并优化 keep 规则。

检查库的优化情况

集成第三方库时,这些库通常会包含自己的消费者保留规则,以便与 R8 搭配使用。由于库作者无法预测您的具体实现,因此他们有时会编写保守的、影响范围广泛的规则,这些规则会阻止对比实际需要更多的类、字段和方法进行优化。这可能会阻止 R8 优化与库的实际运行时执行无关的应用部分。您可以使用 R8 配置分析器来识别引入了对应用优化产生负面影响的规则的库。

使用配置分析器检查所有合并的消费者保留规则的综合效果。通过分析来自第三方库的每条保留规则的影响,您可以识别并跟踪阻止应用进行大量优化的特定第三方库。

如何优化库

如需解决第三方库引入的 keep 规则,请执行以下操作:

  • 如果某个库包含过于宽泛的规则,我们建议您联系该库的维护人员,并提供报告中的数据,以说明其当前规则对应用优化得分的影响。如果是外部库,请在提交问题之前查找该库中是否存在现有 bug。
  • 如有必要,您可以过滤掉特定库中的规则,以测试潜在的改进。您可以将库的规则导入到项目中,排除宽泛的规则,然后重新运行配置分析器,以衡量大小和性能方面的潜在增益。

被涵盖的规则

在某些情况下,多条保留规则可能会重叠,其中一条规则可能会阻止进行不必要的优化。如果代码库中有两个 keep 规则。

# Prevents optimization in the entire package
# Remove this to improve optimization
-keep class com.example.package.** { *; }

# Prevents optimization to the class inside the package
-keep class com.example.package.Myclass

第一个禁止优化整个软件包的 keep 规则涵盖了第二个 keep 规则,而第二个 keep 规则的目标是第一个 keep 规则所保留的软件包中的类。当保留规则重叠时,其中一条规则可能会阻止超出所需范围的优化。通过优化这些重叠的规则,您可以最大限度地提高 R8 优化效果并消除技术债务。此过程涉及简化配置,以确保仅保留必要的代码,同时充分发挥 R8 优化功能的潜力。

报告摘要部分示例
图 4. 报告中被涵盖的规则示例。

优化被涵盖的规则

  1. 使用 R8 Configuration Analyzer 查找被涵盖的保留规则。
  2. 确定代码库中实际依赖于反射的确切类、字段或方法,这些类、字段或方法需要使用 keep 规则保留。了解这一点有助于您优化保留规则。
  3. 使用配置分析器,比较以相同类、字段或方法为目标的每条规则的影响。您可以使用每条保留规则阻止的优化百分比来确定哪些是宽泛的保留规则,哪些是精细的保留规则。
    1. 如果精细规则编写得非常精确,仅保留以反射方式访问的确切成员或类,则移除较宽泛的 keep 规则。这样可以安全地为软件包的其余部分解锁 R8 优化。
    2. 如果宽泛规则定位的是正确的班级,请保留宽泛规则并删除精细规则。窄规则只是冗余的杂乱内容。 请务必优化宽泛的规则,使其仅以您已识别的类、字段或方法为目标。

验证并测试您的更改:重新运行配置分析器,确保冲突已得到解决。然后,编译发布版本并测试您的更改,以确保代码库按预期运行。

移除不必要的规则

借助配置分析器,您可以系统地审核代码库,以识别并剪除使配置变得杂乱的过时保留规则。R8 配置分析器专门突出显示了不必要规则的两个主要来源:

  • 未使用的规则:与当前 build 中的零个类、方法或字段匹配的规则。它们通常在代码重构、移除依赖项后或从不再相关的复制粘贴配置中保留下来,从而增加了不必要的配置复杂性。
  • 相同的规则:相同的 keep 规则是指以相同类、字段和方法为目标的规则,或者在同一 keep 规则文件或不同 keep 规则文件中重复声明的 keep 规则。

这两种类型的规则都会使配置变得杂乱无章,从而难以维护和调试。通过识别这些问题,您可以清理配置。