Oprócz ogólnych reguł przechowywania, dodatkowych typów reguł przechowywania i opcji globalnych możesz używać określonych reguł do rozwiązywania problemów z optymalizacją.
-checkdiscard
Reguła -checkdiscard pozwala sprawdzić, czy R8 odrzucił klasę lub jej element, które miały zostać usunięte. Jeśli określona klasa lub element nie zostaną odrzucone, kompilacja się nie powiedzie.
Składnia elementu -checkdiscard jest taka:
-checkdiscard <class_specification>
W tym przykładzie kompilacja nie powiedzie się, jeśli zachowane zostanie pole userId lub metoda setLabel() z klasy com.example.models.User:
-checkdiscard class com.example.models.User{
private java.lang.String userId;
public void setLabel(java.lang.String);
}
Kod klasy może nadal być obecny w aplikacji, jeśli jej metody zostały wstawione w inne klasy. Aby mieć pewność, że kod został całkowicie usunięty, a nie tylko wstawiony, dodaj odpowiednią regułę, która uniemożliwia R8 przeprowadzanie optymalizacji w klasie docelowej, łącząc -checkdiscard z regułą -keep,allowshrinking. Uniemożliwia to optymalizacje takie jak łączenie klas i wstawianie kodu. Jeśli reguła -checkdiscard zostanie spełniona, żadne treści z pasujących klas nie będą znajdować się w zoptymalizowanej aplikacji.
Ten przykład pokazuje, jak to zrobić:
# 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
Użyj reguły -whyareyoukeeping, aby dowiedzieć się, dlaczego R8 zachował w kompilacji aplikacji konkretną klasę, pole lub metodę. Element może być przechowywany z wielu powodów, ale ta reguła podaje tylko ten, który wyjaśnia najkrótszą ścieżkę do elementu z przechowywanego elementu. Jeśli usuniesz tę ścieżkę z kodu, produkt może nadal być zachowany, ale z innego powodu.
Możliwe przyczyny:
Reguła zachowywania: reguła zachowywania może pochodzić z aplikacji, używanej biblioteki lub reguł wygenerowanych przez AAPT (Android Asset Packaging Tool).
Odwołania przechodnie z zachowanego kodu lub zasobów: jeśli R8 zachowuje kod lub XML (np. układy), wszystko, do czego statycznie się odwołuje, jest zachowywane.
Składnia:
-whyareyoukeeping <class_specification>
Na przykład:
-whyareyoukeeping class com.example.foo.MainActivity {
private void setLabel(...);
}
Dane wyjściowe są drukowane w konsoli.
Jeśli nie masz reguły, która zachowuje setLabel(), wynik to:
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()
Jeśli masz regułę przechowywania kierowaną na setLabel(), dane wyjściowe będą podobne do tych:
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