添加全局选项

R8 提供了一些全局选项,这些选项要么会修改整个应用中的 R8 优化,要么会影响每条 keep 规则。这些选项与保留规则一起保存在 proguard-rules.pro 文件中。其中一些全局选项用于配置额外的优化,而另一些则用于关闭优化的某些方面。

用于额外优化的全局选项

以下全局选项可实现额外的优化:

  • -repackageclasses [<optional-package-name>]:将类重新打包到单个指定软件包中,以进一步减小应用大小。如果您未提供可选的软件包名称,则这些类会移至空的默认软件包中。这是建议的应用设置。
  • -allowaccessmodification:允许 R8 更改(通常是扩大)类、字段和方法的公开范围,以执行更广泛的优化。使用 proguard-android-optimize.txt 时启用。自 Android Gradle 插件 (AGP) 8.2 起,如果您在完整模式下使用 R8,则这是默认配置。

以下是启用额外优化的配置示例:

-repackageclasses
-allowaccessmodification

用于限制优化的全局选项

通过以下全局选项,您可以关闭应用优化的某些方面,这在您优化保留规则或首次启用 R8 时非常有用。

  • -dontoptimize:防止代码优化,例如方法内联。 此选项可在开发期间使用,但不应在正式版 build 中使用。
  • -dontshrink:防止移除未引用的代码和进行代码优化。此选项可在开发期间使用,但不应在正式版 build 中使用。
  • -dontobfuscate:防止缩短类和方法的名称。在调试期间,关闭混淆功能尤其有助于更轻松地读取堆栈轨迹。此选项可在开发期间使用,但不应在正式版 build 中使用。
  • -keepattributes <attributes>:接受应保留的属性的英文逗号分隔列表。如果您使用默认的 proguard-android-optimize.txt,R8 会剥离包括 RuntimeVisibleAnnotationsSignature 在内的所有属性,但如果需要在反射等情况下保留这些属性,这可能会很有用。如需查看您可以指定的属性列表,请参阅保留属性

保留属性

属性是附加到代码不同部分的额外信息。属性用于存储代码中的注释和通用签名等信息。

某些反射操作需要保留特定属性才能成功执行。例如:

  • 使用 getEnclosingMethod()getDeclaredClasses() 访问内部或外部类结构时,需要 EnclosingMethodInnerClasses 属性。
  • 使用 getTypeParameters() 访问通用签名时,需要 Signature 属性。
  • 使用 getAnnotation() 访问注释时,需要 RuntimeVisibleAnnotations 属性。

常用必需属性

使用默认 Proguard 文件(proguard-android-optimize.txtproguard-android.txt)时,Android Gradle 插件 (AGP) 会保留以下属性。请注意,其中一些属性需要较新版本的 AGP:

属性 说明
AnnotationDefault 此属性位于注释类型本身上,用于存储注释元素的默认值。

注意:自 AGP 7.1 起,此属性默认保留,仅在使用早期版本 AGP 的应用中需要明确保留。
EnclosingMethod 此属性存在于非本地类或匿名类中的内部类中。它用于标识直接包含该类的方法或初始化程序。
InnerClasses 此属性记录了在另一个类中定义的嵌套类(内部类、静态嵌套类、局部类和匿名类)的相关信息。
LineNumberTable 此属性将字节码指令映射到原始源文件中的相应行号。

注意:自 Android Gradle 插件 (AGP) 8.6 起,此属性默认保留,仅在使用较低版本 AGP 的应用中需要明确保留。
RuntimeVisibleAnnotations 此属性用于存储可通过反射在运行时看到的注释。

通常,如果在运行时使用注释,这是应用和库消费者规则所需的 *Annotation 属性中的唯一注释。
RuntimeVisibleParameterAnnotations 此属性存储通过反射在方法参数上运行时可见的注释。
RuntimeVisibleTypeAnnotations 此属性用于存储适用于类型使用(而不仅仅是声明)的注释。此属性在运行时可见。
Signature 此属性用于存储类、方法和字段的更通用类型签名,尤其是在它们使用泛型(如 List<String>)时。
SourceFile 此属性存储了编译类的源文件(.kt.java 文件)的名称。调试器主要使用它在逐步调试已编译的 Java 代码时显示原始源代码行。它可帮助开发者将执行轨迹追溯到他们编写的代码。

注意:自 AGP 8.2 起,此属性默认保留,仅在使用早期版本的 AGP 的应用中需要显式保留。

对于使用 proguard-android-optimize.txt 的应用,在大多数情况下,由 AGP 定义的保留规则都足够了。不过,如果您要为库编写代码,则应在其消费者保留规则中指定库所需的所有属性,即使这些属性已在此列表中定义。这样可确保,即使开发者决定不包含 proguard-android-optimize.txt,您的库也能正常运行。

其他保留属性

您可以指定要保留的其他属性,不过在绝大多数反射或 JNI 访问场景中,这些属性都不是必需的。不过,在优化库时,其中一些可能仍会经常使用。

属性 说明
MethodParameters 此属性提供有关方法参数的信息,特别是它们的名称和访问标志。
Exceptions 此属性列出了方法声明要抛出的已检查异常。

此属性通常不用于应用。对于库作者,它通常不会用于消费者保留规则,但经常用于构建库。如需详细了解如何优化库,请参阅面向库作者的优化
RuntimeInvisibleAnnotations 此属性用于存储在运行时通过反射在类、字段或方法上不可见的注释。

应用开发者不应保留此属性。对于库作者,此属性与消费者 keep 规则无关,但在构建库时经常使用。如需详细了解如何优化库,请参阅面向库作者的优化
RuntimeInvisibleParameterAnnotations 此属性存储在方法参数上通过反射在运行时不可见的注释。

应用开发者不应保留此属性。对于库作者,此属性与消费者 keep 规则无关,但在构建库时经常使用。如需详细了解如何优化库,请参阅面向库作者的优化
RuntimeInvisibleTypeAnnotations 此属性用于存储适用于类型使用(而不仅仅是声明)的注释。此属性在运行时不可见。

应用开发者不应保留此属性。对于库作者,此属性与消费者 keep 规则无关,但在构建库时经常使用。如需详细了解如何优化库,请参阅面向库作者的优化