除了常规的保留规则、其他保留规则类型和全局选项之外,您还可以使用某些规则来排查优化问题。
-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