使用规则排查优化问题

除了常规的保留规则其他保留规则类型全局选项之外,您还可以使用某些规则来排查优化问题。

-checkdiscard

借助 -checkdiscard 规则,您可以检查 R8 是否已成功舍弃您预期要移除的类或其成员。如果未舍弃指定的类或成员,则 build 会失败。

-checkdiscard 的语法如下所示:


-checkdiscard <class_specification>

在以下示例中,如果保留 com.example.models.User 类中的 userId 字段或 setLabel() 方法,则 build 会失败:

-checkdiscard class com.example.models.User{
  private java.lang.String userId;
  public void setLabel(java.lang.String);
}

如果该类的方法已内嵌到其他类中,则该类的代码可能仍存在于应用中。为确保代码已完全移除,而不仅仅是内联,请添加相应的规则,通过将 -checkdiscard-keep,allowshrinking 规则相结合,防止 R8 对目标类执行优化。这会禁止类合并和内嵌等优化。如果 -checkdiscard 规则通过,则匹配的类中的所有内容都不会包含在优化后的应用中。

以下示例演示了此用法:

# Either keep or remove the class, don't rename or otherwise optimize it
-keep,allowshrinking class com.example.foo { *; }

# Verify that the class and all of its fields and methods are removed.
-checkdiscard class com.example.foo

-whyareyoukeeping

使用 -whyareyoukeeping 规则来确定 R8 在应用 build 中保留特定类、字段或方法的原因。内容可以因多种原因而保留;不过,此规则仅提供从保留的内容到相应内容的最短路径。如果您从代码中移除此路径,您可能仍会看到保留的商品,但原因不同。

可能的原因包括:

  • 保留规则:保留规则可以来自应用、使用的库,也可以是 AAPT(Android 资源打包工具)生成的规则。

  • 来自保留的代码或资源的可传递引用:如果代码或 XML(例如布局)被 R8 保留,则其静态引用的任何内容也会被保留。

语法如下:


-whyareyoukeeping <class_specification>

例如:

-whyareyoukeeping class com.example.foo.MainActivity {
  private void setLabel(...);
}

输出将显示在控制台中。

如果您没有任何规则来保留 setLabel(),则输出如下:

com.example.foo.MainActivity
|- is referenced in keep rule:
|  /app/build/intermediates/aapt_proguard_file/release/processReleaseResources/aapt_rules.txt:4:1
Nothing is keeping void com.example.foo.MainActivity.setLabel()

如果您有以 setLabel() 为目标的保留规则,则输出类似于以下内容:

com.example.foo.MainActivity
|- is referenced in keep rule:
| /app/proguard-rules.pro:23:1
void com.example.foo.MainActivity.setLabel()
|- is referenced in keep rule:
|  /app/proguard-rules.pro:23:1