通过 R8 启用应用优化

为了获得最佳用户体验,您应该优化应用,使其尽可能小且快。我们的应用优化器(称为 R8)通过移除未使用的代码和资源、重写代码以优化运行时性能等方式来简化应用。对于您的用户而言,这意味着:

  • 更快启动
  • 降低内存用量
  • 提升渲染和运行时性能
  • ANR 错误减少了 30%

R8 优化概览

R8 使用多阶段流程来优化应用的大小和速度。主要操作包括:

  • 代码缩减(也称为“摇树优化”):R8 会识别并移除 应用及其库依赖项中无法访问的代码。通过分析应用的入口点(例如清单中定义的 ActivitiesServices),R8 会构建引用代码图,并移除所有未被引用的内容。

  • 逻辑优化:R8 会重写代码,以提高执行 效率并减少开销。主要技术包括:

    • 方法内联:R8 会将方法调用处替换为被调用方法的实际正文 。这样可以消除函数调用的开销,并让 R8 执行进一步的优化。

    • 类合并:R8 会将一组类和接口合并为一个 类。这样可以减少应用中的类数量,从而降低内存压力并提高启动速度。

  • 混淆处理(也称为“缩减”):为了减小 DEX 文件的大小,R8 会缩短类、字段和方法的名称(例如, com.example.MyActivity 可能会变为 a.b.a)。

自 Android Gradle 插件 (AGP) 8.12.0 版起,R8 也会在其优化阶段优化资源。如需了解详情,请参阅优化型 资源缩减

启用优化

如需为应用启用应用优化,请根据项目的 AGP 版本使用相应的 DSL。我们建议仅在您发布前测试的最终版本(通常是发布 build)中启用应用优化,因为优化会增加项目的 build 时间,并且由于其修改代码的方式,可能会使调试更加困难。

对于 AGP 9.3 及更高版本

如需为 AGP 9.3 及更高版本启用应用优化,请执行以下操作:

  • 在发布 build 的应用级 build 脚本的 optimization 块中设置 enable = true
  • keep 规则添加到 src/<variant>/keepRules源代码集中以 .keep 为后缀的文件中。例如,src/main/keepRules/custom-rules.keep

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

适用于低于 9.3 的 AGP 版本的旧版 DSL

如需启用应用优化,请在发布 build的应用级 build 脚本中设置 isMinifyEnabled = true(用于代码优化) 和 isShrinkResources = true(用于资源优化)。我们建议您始终同时启用这两个设置。

旧版 DSL (Kotlin)

android {
    buildTypes {
        release {

            // Enables code optimizations.
            isMinifyEnabled = true

            // Enables resource shrinking.
            isShrinkResources = true

            proguardFiles(
                // Default file with automatically generated optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),

                ...
            )
            ...
        }
    }
    ...
}

旧版 DSL (Groovy)

android {
    buildTypes {
        release {

            // Enables code optimizations.
            minifyEnabled = true

            // Enables resource shrinking.
            shrinkResources = true

            // Default file with automatically generated optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')

            ...
        }
    }
}

改进 R8 优化

R8 的性能优势与 R8 能够优化的代码库量直接相关。如需充分发挥 R8 的优势,请遵循以下最佳实践:

如需帮助您优化 keep 规则,请使用 R8 配置分析器

借助 R8 配置分析器,您可以执行以下操作:

  • 通过监控 R8 配置分析器报告提供的指标,跟踪和改进整体 R8 配置质量。
  • 查找最宽泛的 keep 规则(即阻止最多优化的规则)
  • 并了解它们阻止了哪些优化,以便对其进行优化。

R8 配置分析器在 AGP 9.3.0-alpha05 版或 R8 9.3.7-dev 版中提供。如需了解详情,请参阅分析 R8 配置

优化资源缩减,以进一步减小应用大小

AGP 8.12.0 版引入了优化型资源缩减,旨在集成资源和代码优化,以创建更小、更快的应用。 在优化型资源缩减之前,Android 资源打包工具 (AAPT2) 生成的 keep 规则有效地将资源缩减与代码分开处理,通常会保留相互引用的无法访问的代码或资源。

借助优化型资源缩减,资源被视为程序代码的一部分,形成引用图。当代码或资源的集合未被引用时,它不受 keep 规则的保护,并且可以被移除。

启用优化型资源缩减

如需为 AGP 8.12 或 8.13 启用新的优化型资源缩减流水线,请将以下内容添加到项目的 gradle.properties 文件中:

android.r8.optimizedResourceShrinking=true

如果您使用的是 AGP 9.0.0 或更高版本,则无需设置 android.r8.optimizedResourceShrinking=true。当在 build 配置中启用 isShrinkResources = true 时,系统会自动应用优化型资源缩减。

验证和配置 R8 优化设置

如需让 R8 使用其 完整的优化功能,请从项目的 gradle.properties 文件中移除 以下行(如果存在):

android.enableR8.fullMode=false

请注意,启用应用优化会使堆栈轨迹难以理解,尤其是在 R8 重命名类或方法名称的情况下。如需获取与源代码 正确对应的堆栈轨迹,请参阅恢复原始堆栈 轨迹

如果启用了 R8,您还应创建启动配置文件,以获得更好的 启动性能。

如果您启用了应用优化,但它导致了错误,请尝试以下策略来修复这些错误:

如果您有兴趣优化 build 速度,请参阅配置 R8 的运行方式,了解如何根据您的环境配置 R8。

AGP 和 R8 版本行为变更

下表概述了 Android Gradle 插件 (AGP) 和 R8 编译器的各个版本中引入的主要功能。

AGP 版本 引入的功能
9.3 简化的 DSL:新的 `optimization {}` 块需要较少的配置 - 优化型资源缩减始终处于启用状态,默认 Android keep 规则是选择停用。

`keepRules` 源代码集: 如果您使用新的 DSL,则必须将 keep 规则放在 src/<variant>/keepRules 源代码集中,放在以 .keep 为后缀的文件中。这些源代码集也与旧版 DSL 兼容。

KMP(Kotlin MultiPlatform)使用者规则: KMP 不再需要设置 publish = true,并且支持带有 .keep 扩展名的 src/<variant>/keepRules 源代码集。

请注意,旧版 DSL 仍受支持。
9.1 默认情况下重新打包类: R8 会重新打包类(将其移至顶层的未命名软件包),以进一步压缩 DEX,从而无需指定 -repackageclasses 选项。如需了解其运作方式以及如何选择停用,请参阅全局选项
9.0 优化型资源缩减: 默认处于启用状态(使用 android.r8.optimizedResourceShrinking 进行控制)。优化型资源缩减 有助于将资源缩减与代码优化流水线集成,从而创建更小、更快的应用。通过同时优化代码和资源引用,它可以识别并移除仅从未使用过的代码引用的资源。与之前的单独优化流程相比,这是一个重大改进。

这对于在不同外形规格垂直领域共享大量资源和代码的应用尤其有用,应用大小的改进幅度超过 50%。由此带来的大小缩减可减少下载量、加快安装速度,并为用户带来更好的体验,包括更快的启动速度、改进的渲染效果和更少的 ANR 错误。

库规则过滤: 库使用者规则中对全局选项(例如 -dontobfuscate)的支持已移除,应用会将其过滤掉。如需了解详情,请参阅添加全局选项

Kotlin null 检查: 默认情况下已优化(使用 -processkotlinnullchecks 进行控制)。此版本还在 build 速度方面进行了重大改进。如需了解详情,请参阅全局选项,了解其他优化

优化特定软件包: 您可以使用 packageScope 优化特定软件包。此功能尚处于实验阶段。如需了解详情,请参阅使用packageScope优化指定的软件包。

默认情况下已优化: 对 getDefaultProguardFile("proguard-android.txt") 的支持已移除,因为它包含应避免使用的 -dontoptimize。请改用 "proguard-android-optimize.txt"。如果您需要在应用中全局停用优化,请手动将该标志添加到 ProGuard 文件中
8.12 优化型资源缩减: 添加了初始支持(使用 android.r8.optimizedResourceShrinking 进行控制)。优化型资源缩减 有助于将资源缩减与代码优化流水线集成。您必须在此版本的 AGP 中手动启用它。

Logcat 轨迹还原: 支持在 Android Studio Logcat 窗口中自动轨迹还原。
8.6 改进的轨迹还原: 默认情况下,所有 minSdk 级别都包含文件名和行号轨迹还原(之前在 8.2 版中需要 minSdk 26+)。

更新 R8 有助于确保经过混淆处理的 build 中的堆栈轨迹清晰易读。此版本改进了行号和源文件的映射方式,使 Android Studio Logcat 等工具能够更轻松地自动将崩溃轨迹还原到原始源代码。
8.0 默认情况下处于完整模式R8 完整模式 提供了更强大的优化功能。该功能默认处于启用状态。您可以使用 android.enableR8.fullMode=false 选择停用。
7.0 提供完整模式: 作为选择启用功能引入,使用 android.enableR8.fullMode=true。完整模式通过对代码如何使用反射和其他动态功能做出更严格的假设,应用了更强大的优化。虽然它可以减小应用大小并提高性能,但可能需要额外的 keep 规则来防止必要的代码被剥离。

将 R8 与其他 build 系统搭配使用

虽然 AGP 是 Android 应用的推荐构建系统,并且受到官方支持,但您也可以使用 Bazel 等替代构建系统。如果您使用的是 Bazel,可以将 R8 集成到 build 流水线中,以缩减、混淆处理和优化应用。

如需了解如何使用 Bazel 优化 Android 应用,请参阅 Bazel 的 rules_android文档。请注意,Bazel 未 正式支持 Android 应用开发。