Используйте правила для устранения неполадок в процессе оптимизации.

Помимо общих правил сохранения , дополнительных типов правил сохранения и глобальных параметров , вы можете использовать определенные правила для устранения неполадок в процессе оптимизации.

-checkdiscard

Правило -checkdiscard позволяет проверить, успешно ли R8 удалил класс или его член, который вы ожидали удалить. Если указанный класс или член не удален, сборка завершается с ошибкой.

Синтаксис параметра -checkdiscard выглядит следующим образом:


-checkdiscard <class_specification>

В следующем примере сборка завершается с ошибкой, если сохраняется либо поле userId , либо метод setLabel() из класса com.example.models.User :

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

Код класса может оставаться в приложении, если его методы были встроены в другие классы. Чтобы убедиться, что код был полностью удален, а не просто встроен, добавьте соответствующее правило, которое запрещает R8 выполнять оптимизации целевого класса, объединив правило -checkdiscard с правилом -keep,allowshrinking . Это запрещает такие оптимизации, как слияние классов и встраивание. Если правило -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 сохранил определенный класс, поле или метод в сборке вашего приложения. Элемент может быть сохранен по нескольким причинам; однако это правило предоставляет только ту, которая объясняет кратчайший путь к элементу от сохраненного элемента. Если вы удалите этот путь из своего кода, вы все равно можете увидеть, что элемент сохранен, но по другой причине.

Возможные причины:

  • Правило сохранения : Правило сохранения может быть взято из самого приложения, используемой библиотеки или правил, сгенерированных инструментом AAPT (Android Asset Packaging Tool).

  • Транзитивные ссылки из сохраненного кода или ресурсов : если код или 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