保留规则简介

如果您使用默认设置启用应用优化,R8 会执行广泛的优化,以最大限度地提高性能。R8 会对代码进行大幅修改,包括重命名、移动和移除类、字段和方法。如果您发现这些修改会导致错误,则需要通过在保留规则中声明 R8 不应修改的代码部分来指定这些部分。

需要保留规则的常见场景

R8 会识别并保留代码中的所有直接调用。不过,R8 无法看到间接的代码使用情况,这可能会导致它移除应用需要的代码,从而导致崩溃。您可以使用保留规则来告知 R8 保留此类间接使用的代码。以下是一些常见情况,您可能需要保留规则:

  • 通过反射访问的代码:R8 无法识别何时通过反射访问类、字段或方法。例如,R8 无法识别通过名称使用 Class.getDeclaredMethod() 查找的方法或使用 Class.getAnnotation() 检索到的注释。在这些情况下,R8 可能会重命名这些方法和注释或完全移除它们,从而导致运行时出现 ClassNotFoundExceptionNoSuchMethodException
  • 通过 Java 原生接口 (JNI) 调用的代码:当原生(C 或 C++)代码调用 Java 或 Kotlin 方法,或者 Java 或 Kotlin 代码通过 JNI 调用 C++ 代码时,调用基于对方法名称的动态字符串查找。R8 无法看到基于动态字符串的方法调用,因此其优化可能会破坏您的代码。

以下并非需要保留规则的详尽场景列表,但这些场景涵盖了您可能需要保留规则的大多数情况。

如何向应用添加保留规则

您应将规则添加到应用模块根目录中的 proguard-rules.pro 文件中;该文件可能已存在,但如果不存在,请创建该文件。如需应用文件中的规则,您必须在模块级 build.gradle.kts(或 build.gradle)文件中声明该文件,如以下代码所示:

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile("proguard-android-optimize.txt"),

                // File with your custom rules
                "proguard-rules.pro"
            )
           // ...
        }
    }
    // ...
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile('proguard-android-optimize.txt'),

                // File with your custom rules.
                'proguard-rules.pro'
            )
           // ...
        }
    }
    // ...
}

默认情况下,您的 build 文件还包含 proguard-android-optimize.txt 文件。此文件包含大多数 Android 项目所需的规则,因此您应让其保留在 build 文件中。此文件基于 proguard-common.txt 文件,并与其共享内容。

较大的应用通常在多个库模块中包含代码。在这种情况下,最好将 keep 规则与它们所适用的代码放在特定库模块中。在为库维护保留规则时,关键区别在于如何在库模块的 build.gradle.kts(或 build.gradle)文件中声明这些规则。如需了解详情,请参阅面向库作者的优化

添加保留规则

添加保留规则时,您可以添加全局选项,也可以定义自己的保留规则。

  • 全局选项:全局选项是影响 R8 如何对整个代码库进行操作的常规指令。如需了解详情,请参阅全局选项
  • 保留规则:保留规则需要精心设计,以确保您在最大限度优化代码的同时,不会意外中断应用。如需了解您自己的保留规则的语法,请参阅保留规则语法

面向库作者的规则

在了解了保留规则的全局选项和语法后,请参阅面向库作者的优化,了解更多详情。