如果您使用默认设置启用应用优化,R8 会执行广泛的优化,以最大限度地提高性能。R8 会对代码进行大幅修改,包括重命名、移动和移除类、字段和方法。如果您发现这些修改会导致错误,则需要通过在保留规则中声明 R8 不应修改的代码部分来指定这些部分。
需要保留规则的常见场景
R8 会识别并保留代码中的所有直接调用。不过,R8 无法看到间接的代码使用情况,这可能会导致它移除应用需要的代码,从而导致崩溃。您可以使用保留规则来告知 R8 保留此类间接使用的代码。以下是一些常见情况,您可能需要保留规则:
- 通过反射访问的代码:R8 无法识别何时通过反射访问类、字段或方法。例如,R8 无法识别通过名称使用
Class.getDeclaredMethod()
查找的方法或使用Class.getAnnotation()
检索到的注释。在这些情况下,R8 可能会重命名这些方法和注释或完全移除它们,从而导致运行时出现ClassNotFoundException
或NoSuchMethodException
。 - 通过 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 如何对整个代码库进行操作的常规指令。如需了解详情,请参阅全局选项。
- 保留规则:保留规则需要精心设计,以确保您在最大限度优化代码的同时,不会意外中断应用。如需了解您自己的保留规则的语法,请参阅保留规则语法。
面向库作者的规则
在了解了保留规则的全局选项和语法后,请参阅面向库作者的优化,了解更多详情。