解决优化问题

由于 R8 的优化会更新应用的代码,因此务必对应用的行为进行严格 测试,以确保应用按预期运行。如果出现意外行为,请使用本页作为指南,排查优化后可能出现的问题。如需详细了解可用于排查优化问题的 规则,请参阅 使用规则排查优化问题。

排查问题时,请重点关注以下情况:

  • 过度优化导致应用崩溃:您的应用崩溃,因为 R8 优化了过多的代码。
  • 优化不明确或不足:R8 未按您的预期优化应用,或者您需要进一步了解优化。

应用崩溃

如果您的应用在使用 R8 进行优化后崩溃,通常是由于反射中断所致。如需识别反射中断,请遵循以下指南:

  • 您观察到异常,这意味着系统正在通过反射使用指示的类、方法或字段。这些异常通常是以下之一:ClassNotFoundException、NoSuchMethodException、NoSuchFieldException、NoClassDefFoundError、NoSuchMethodError、NoSuchFieldError。
  • 您看到使用 import kotlin.reflect.* 或 import java.lang.reflect.* 引用反射的代码。
  • 您观察到类构造函数的使用方式如下:Something::class.constructors。
  • 您看到 Class.forName(...)。

解决方案:添加保留规则。

如果您的代码执行反射,则可以使用 Jetpack Keep注解对该代码进行注解,而不是添加保留规则。Jetpack Keep lint 检查还会标记其他未注解的反射调用,这有助于您防止类似崩溃。

优化不明确或不足

由于规则是从应用以及包含的库中应用的,因此您可能需要进一步了解所应用的规则,或者需要解释 R8 为何保留了您预期会优化的某些代码段。

  • 所应用的规则存在歧义:由于包含的库中的规则也适用于您的应用,并且这些库中的全局选项也会传播到您的应用,因此您可能不确定应用了哪些规则。

    解决方案:查看 R8 在构建项目时应用的所有 规则的报告,以检查应用了哪些规则。您可以在 ./app/build/outputs/mapping/configuration.txt 中找到此报告。此报告包含用于配置 R8 的每个库和模块中的所有合并规则,可用于识别低效规则。

  • 保留的代码过多:R8 的优化可能会保留您 预期会移除的代码。

    解决方案:使用配置选项 -whyareyoukeeping 来帮助 了解代码为何被保留。输出包含从保留的代码到应用的一个入口点的路径。如需了解详情,请参阅 -whyareyoukeeping。

  • 难以理解原始堆栈轨迹:R8 以 各种方式 更改代码,导致堆栈轨迹不再引用原始代码。例如,行号以及类和方法的名称可能会发生变化。

    解决方案:从 Android Studio Otter 3 Feature Drop 和 AGP 9.0 开始, Logcat 会自动对堆栈轨迹进行反混淆处理。不过,如果您使用的是旧版 Android Studio,则需要手动恢复原始堆栈轨迹。如需恢复原始堆栈轨迹,请使用 retrace 命令行工具,该工具与 命令行工具软件包捆绑在一起。

    如需使用 retrace,请向该命令提供映射文件和堆栈轨迹文件的路径。映射文件(名为 mapping.txt)会自动与 Android App Bundle (AAB) 捆绑在一起。如需了解详情,请参阅 retrace文档和 Play 管理中心帮助中心文章,了解 如何对崩溃堆栈轨迹进行反混淆处理。使用 Play 和 Firebase Crashlytics 时,请将 mapping.txt 文件与服务从应用用户处收集的崩溃信息一起使用。以下命令展示了如何从项目的根目录运行 retrace:

    $ANDROID_HOME/cmdline-tools/latest/bin/retrace app/build/outputs/mapping/$releaseVariant/mapping.txt trace.txt
    

报告错误

如果您无法解决 R8 问题,请提交 bug。