Use rules to troubleshoot optimization

Apart from the general keep rules, additional keep rule types, and global options, you can use certain rules to troubleshoot your optimization.

-checkdiscard

The -checkdiscard rule lets you check whether R8 has successfully discarded a class or its member that you expected to be removed. If the specified class or member isn't discarded, the build fails.

The syntax for -checkdiscard is as follows:


-checkdiscard <class_specification>

In the following example, the build fails if either the userId field or the setLabel() method from the com.example.models.User class is retained:

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

The class's code might still be present in the app if its methods were inlined into other classes. To make sure that the code has been completely removed and not just inlined, add a corresponding rule that prevents R8 from performing optimizations on the target class, by combining -checkdiscard with a -keep,allowshrinking rule. This prohibits optimizations such as class merging and inlining. If the -checkdiscard rule passes, then none of the contents from the matched classes are in the optimized app.

The following example demonstrates this usage:

# 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

Use the -whyareyoukeeping rule to determine why R8 kept a specific class, field, or method in your app's build. An item can be kept for multiple reasons; however, this rule only provides the one that explains the shortest path to the item from a kept item. If you remove this path from your code, you might still see the item retained but for a different reason.

The possible reasons are:

  • A keep rule: The keep rule can be from the app, a consumed library, or rules generated by AAPT (Android Asset Packaging Tool).

  • Transitive references from kept code or resources: If code or XML (such as layouts) is retained by R8, anything it statically references is kept.

The syntax is:


-whyareyoukeeping <class_specification>

For example:

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

The output is printed to the console.

If you don't have any rule keeping setLabel(), the output is:

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()

If you have a keep rule targeting setLabel(), the output is similar to the following:

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