Dodawanie opcji globalnych

R8 udostępnia opcje globalne, które modyfikują optymalizacje R8 w całej aplikacji lub wpływają na każdą regułę zachowywania. Te opcje są przechowywane w pliku proguard-rules.pro wraz z regułami przechowywania. Niektóre z tych opcji globalnych konfigurują dodatkową optymalizację, a inne wyłączają pewne aspekty optymalizacji.

R8 akceptuje też niektóre starsze opcje przeniesione z ProGuarda, ale je ignoruje. Więcej informacji znajdziesz w sekcji Usuwanie starszych opcji ProGuard.

Opcje globalne dotyczące dodatkowej optymalizacji

Te opcje globalne umożliwiają dodatkową optymalizację:

  • -repackageclasses [<optional-package-name>]: Przekształca klasy w jeden pakiet, aby zmniejszyć rozmiar aplikacji. Jeśli nie podasz opcjonalnej nazwy pakietu, klasy zostaną przeniesione do nienazwanego (domyślnego) pakietu. Jest to zalecane ustawienie w przypadku aplikacji, ponieważ powoduje zmniejszenie rozmiaru plików DEX przez pominięcie prefiksu pakietu w nazwach klas. Od wersji 9.1 wtyczki Androida do obsługi Gradle (AGP) jest to domyślna konfiguracja aplikacji. Aby zrezygnować z tej optymalizacji, użyj ustawienia -dontrepackage.
  • -allowaccessmodification: umożliwia R8 zmianę (zwykle poszerzenie) widoczności klas, pól i metod w celu przeprowadzenia bardziej zaawansowanych optymalizacji. Włączone, gdy używana jest właściwość proguard-android-optimize.txt. Od wersji 8.2 wtyczki Androida do obsługi Gradle (AGP) jest to konfiguracja domyślna, jeśli włączysz pełną optymalizację za pomocą R8.
  • -processkotlinnullchecks [level]: umożliwia R8 zmianę sprawdzania wartości null w funkcjach wewnętrznych Kotlin na usunięcie tylko komunikatu o błędzie lub całkowite usunięcie jawnego sprawdzania wartości null.

    Wartości level, uporządkowane od najsłabszej do najsilniejszej, mają następujący wpływ:

    • keep nie zmienia weryfikacji.
    • remove_message przepisuje każde wywołanie metody sprawdzania na wywołanie funkcji getClass() na pierwszym argumencie wywołania (skutecznie zachowując sprawdzanie wartości null, ale bez żadnej wiadomości).
    • remove całkowicie usuwa weryfikację.

    Domyślnie R8 używa remove_message. Każda specyfikacja -processkotlinnullchecks zastępuje to ustawienie. Jeśli zostanie określony kilka razy, użyta zostanie najsilniejsza wartość.

    -processkotlinnullchecks jest obsługiwane od AGP 9.0.0.

Oto przykład konfiguracji z włączoną dodatkową optymalizacją:

-repackageclasses
-allowaccessmodification

Opcje globalne ograniczające optymalizację

Poniższe opcje globalne umożliwiają wyłączenie niektórych aspektów optymalizacji aplikacji i są przydatne podczas dopracowywania reguł zachowywania lub włączania R8 po raz pierwszy.

  • -dontoptimize: zapobiega optymalizacji kodu, np. wstawianiu metod. Tej opcji można używać podczas programowania, ale nie należy jej stosować w wersjach produkcyjnych.
  • -dontshrink: zapobiega usuwaniu nieużywanego kodu i optymalizacji kodu. Tej opcji można używać podczas programowania, ale nie należy jej stosować w wersjach produkcyjnych.
  • -dontobfuscate: zapobiega skracaniu nazw klas i metod. Może to być szczególnie przydatne podczas debugowania, ponieważ wyłączenie zaciemniania kodu ułatwia odczytywanie śladów stosu. Tej opcji można używać podczas programowania, ale nie należy jej stosować w wersjach produkcyjnych.
  • -keepattributes <attributes>: akceptuje rozdzieloną przecinkami listę atrybutów, które mają zostać zachowane. Jeśli nie używasz domyślnego parametruproguard-android-optimize.txt, R8 usuwa wszystkie atrybuty, w tymRuntimeVisibleAnnotations i Signature. Zachowanie tych atrybutów może być jednak przydatne w przypadkach takich jak refleksja. Listę atrybutów, które możesz określić, znajdziesz w sekcji Zachowaj atrybuty.

Atrybuty zachowywania

Atrybuty to dodatkowe informacje dołączone do różnych części kodu. Przechowują one informacje takie jak adnotacje i ogólne sygnatury z kodu.

Niektóre operacje refleksyjne wymagają zachowania określonych atrybutów, aby można było je przeprowadzić. Na przykład:

  • Podczas uzyskiwania dostępu do struktury klasy wewnętrznej lub zewnętrznej za pomocą poleceń getEnclosingMethod() lub getDeclaredClasses() wymagane są atrybuty EnclosingMethod i InnerClasses.
  • Aby uzyskać dostęp do podpisów ogólnych za pomocą elementu getTypeParameters(), musisz użyć atrybutu Signature.
  • Aby uzyskać dostęp do adnotacji za pomocą getAnnotation(), musisz użyć atrybutu RuntimeVisibleAnnotations.

Często wymagane atrybuty

Gdy używasz domyślnego pliku Proguard (proguard-android-optimize.txt lub proguard-android.txt), wtyczka Androida do obsługi Gradle (AGP) zachowuje te atrybuty: Pamiętaj, że niektóre z tych atrybutów wymagają nowszych wersji AGP:

Atrybut Opis
AnnotationDefault Ten atrybut znajduje się w samych typach adnotacji i przechowuje wartość domyślną elementu adnotacji.

Uwaga: ten atrybut jest domyślnie zachowywany od wersji AGP 7.1. Musi być jawnie zachowywany tylko w aplikacjach korzystających ze starszych wersji AGP.
EnclosingMethod Ten atrybut występuje w klasach wewnętrznych, które nie są klasami lokalnymi ani anonimowymi. Wskazuje metodę lub inicjatora, który bezpośrednio zawiera klasę.
InnerClasses Ten atrybut rejestruje informacje o klasach zagnieżdżonych (klasach wewnętrznych, statycznych klasach zagnieżdżonych, klasach lokalnych i klasach anonimowych) zdefiniowanych w innej klasie.
LineNumberTable Ten atrybut mapuje instrukcje kodu bajtowego na odpowiednie numery wierszy w oryginalnym pliku źródłowym.

Uwaga: ten atrybut jest domyślnie zachowywany od wersji 8.6 wtyczki Androida do obsługi Gradle (AGP) i musi być jawnie zachowywany tylko w aplikacjach korzystających ze starszych wersji AGP.
RuntimeVisibleAnnotations Ten atrybut przechowuje adnotacje, które są widoczne w czasie wykonywania za pomocą refleksji.

Zwykle, jeśli adnotacje są używane w czasie działania, jest to jedyna adnotacja z atrybutów *Annotation, która jest potrzebna aplikacjom i regułom konsumentów biblioteki.
RuntimeVisibleParameterAnnotations Ten atrybut przechowuje adnotacje, które są widoczne w czasie wykonywania za pomocą refleksji na parametrach metody.
RuntimeVisibleTypeAnnotations Ten atrybut przechowuje adnotacje, które mają zastosowanie do użycia typu, a nie tylko do deklaracji. Ten atrybut jest widoczny w czasie wykonywania.
Signature Ten atrybut przechowuje bardziej ogólny typ podpisu dla klas, metod i pól, zwłaszcza gdy używają one typów ogólnych (np. List<String>).
SourceFile Ten atrybut przechowuje nazwę pliku źródłowego (pliku .kt lub .java), z którego skompilowano klasę. Jest on używany głównie przez debugery do wyświetlania oryginalnych wierszy kodu źródłowego podczas przechodzenia przez skompilowany kod Java. Ułatwia programistom śledzenie wykonania aż do napisanego przez nich kodu.

Uwaga: ten atrybut jest domyślnie zachowywany od wersji AGP 8.2. Musi być jawnie zachowywany tylko w aplikacjach korzystających ze starszych wersji AGP.

W przypadku aplikacji korzystających z proguard-android-optimize.txt reguły przechowywania zdefiniowane przez AGP są w większości przypadków wystarczające. Jeśli jednak piszesz kod biblioteki, w jej regułach zachowywania konsumenta musisz określić wszystkie atrybuty wymagane przez bibliotekę, nawet jeśli są one zdefiniowane na tej liście. Dzięki temu Twoja biblioteka będzie solidna, nawet jeśli deweloperzy zdecydują się nie uwzględniać proguard-android-optimize.txt.

Dodatkowe atrybuty zachowywania

Możesz określić dodatkowe atrybuty zachowywania, ale w większości przypadków związanych z refleksją lub dostępem JNI nie są one potrzebne. Niektóre z nich mogą być jednak nadal często używane podczas optymalizacji bibliotek.

Atrybut Opis
MethodParameters Ten atrybut zawiera informacje o parametrach metody, a w szczególności ich nazwy i flagi dostępu.
Exceptions Ten atrybut zawiera listę sprawdzonych wyjątków, które zgłasza metoda.

 Ten atrybut nie jest zwykle używany w przypadku aplikacji. Autorzy bibliotek zwykle nie używają go w regułach przechowywania dla konsumentów, ale często korzystają z niego podczas tworzenia bibliotek. Więcej informacji o optymalizacji bibliotek znajdziesz w artykule Optymalizacja dla autorów bibliotek.
RuntimeInvisibleAnnotations Ten atrybut przechowuje adnotacje, które nie są widoczne w czasie wykonywania za pomocą refleksji w przypadku klasy, pola lub metody.

Deweloperzy aplikacji nie powinni zachowywać tego atrybutu. W przypadku autorów bibliotek ten atrybut nie ma znaczenia w regułach przechowywania konsumentów, ale jest często używany podczas tworzenia bibliotek. Więcej informacji o optymalizacji bibliotek znajdziesz w artykule Optymalizacja dla autorów bibliotek.
RuntimeInvisibleParameterAnnotations Ten atrybut przechowuje adnotacje, które nie są widoczne w czasie wykonywania za pomocą refleksji na parametrach metody.

Deweloperzy aplikacji nie powinni zachowywać tego atrybutu. W przypadku autorów bibliotek ten atrybut nie ma znaczenia w regułach przechowywania konsumentów, ale jest często używany podczas tworzenia bibliotek. Więcej informacji o optymalizacji bibliotek znajdziesz w artykule Optymalizacja dla autorów bibliotek.
RuntimeInvisibleTypeAnnotations Ten atrybut przechowuje adnotacje, które mają zastosowanie do użycia typu, a nie tylko do deklaracji. Ten atrybut nie jest widoczny w czasie wykonywania.

Deweloperzy aplikacji nie powinni zachowywać tego atrybutu. W przypadku autorów bibliotek ten atrybut nie ma znaczenia w regułach przechowywania konsumentów, ale jest często używany podczas tworzenia bibliotek. Więcej informacji o optymalizacji bibliotek znajdziesz w artykule Optymalizacja dla autorów bibliotek.

Usuwanie starszych opcji ProGuard

R8 akceptuje niektóre opcje, które miały wpływ tylko w ProGuard, ale je ignoruje. Te opcje często pozostają w konfiguracjach, które zostały przeniesione z ProGuarda lub skopiowane ze starszych projektów. Nie mają one wpływu na dane wyjściowe R8, więc usuń je z pliku proguard-rules.pro, aby konfiguracja była łatwiejsza do zrozumienia i utrzymania.

R8 ignoruje te opcje bez wyświetlania ostrzeżenia:

  • -adaptkotlinmetadata
  • -android
  • -dontpreverify
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -dontusemixedcaseclassnames
  • -forceprocessing
  • -mergeinterfacesaggressively
  • -optimizationpasses
  • -optimizations
  • -overloadaggressively
  • -target
  • -verbose

R8 ignoruje te opcje i podczas kompilacji zgłasza ostrzeżenie:

R8 nie obsługuje -skipnonpubliclibraryclasses i zgłasza błąd, jeśli konfiguracja zawiera ten element.