Dodawanie opcji globalnych

R8 udostępnia opcje globalne, które modyfikują optymalizacje R8 w całej aplikacji lub wpływają na każdą regułę keep. 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.

Opcje globalne dotyczące dodatkowej optymalizacji

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

  • -repackageclasses [<optional-package-name>]: ponownie pakuje klasy w jednym pakiecie, aby zmniejszyć rozmiar aplikacji. Jeśli nie podasz opcjonalnej nazwy pakietu, klasy zostaną przeniesione do nienazwanego pakietu domyślnego. Jest to zalecane ustawienie w przypadku aplikacji, ponieważ powoduje zmniejszenie rozmiaru plików DEX przez pomijanie prefiksu pakietu w nazwach klas.
  • -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]: pozwala R8 zmienić sprawdzanie wartości null w funkcjach wewnętrznych Kotlin na usunięcie 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 kontroli.
    • remove_message zastępuje każde wywołanie metody sprawdzania wywołaniem funkcji getClass() na pierwszym argumencie wywołania (skutecznie zachowując sprawdzanie wartości null, ale bez żadnej wiadomości).
    • remove całkowicie usuwa weryfikacje.

    Domyślnie R8 używa remove_message. Każda specyfikacja -processkotlinnullchecks zastępuje to ustawienie. Jeśli zostanie podana 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. Są one przydatne podczas dopracowywania reguł zachowywania lub pierwszego włączania R8.

  • -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, gdy wyłączenie zaciemniania 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 oddzieloną przecinkami listę atrybutów, które mają zostać zachowane. Jeśli nie używasz domyślnego ustawienia proguard-android-optimize.txt, R8 usuwa wszystkie atrybuty, w tym RuntimeVisibleAnnotations i Signature. Zachowanie tych atrybutów może być jednak przydatne w przypadkach takich jak odbicie. Listę atrybutów, które możesz określić, znajdziesz w sekcji Zachowaj atrybuty.

Zachowaj atrybuty

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

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

  • Podczas uzyskiwania dostępu do wewnętrznej lub zewnętrznej struktury klasy za pomocą poleceń getEnclosingMethod() lub getDeclaredClasses() wymagane są atrybuty EnclosingMethodInnerClasses.
  • Aby uzyskać dostęp do podpisów ogólnych za pomocą 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 AGP 7.1 i trzeba go jawnie zachować 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 inicjator, który bezpośrednio zawiera klasę.
InnerClasses Ten atrybut rejestruje informacje o zagnieżdżonych klasach (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 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 przez odbicie.

Zazwyczaj, 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 działania programu przez odbicie 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 działania.
Signature Ten atrybut przechowuje bardziej ogólny podpis typu dla klas, metod i pól, zwłaszcza gdy używają one typów generycznych (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 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, które korzystają 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 informacji o użytkownikach 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 programiści zdecydują się nie uwzględniać proguard-android-optimize.txt.

Dodatkowe atrybuty zachowania

Możesz określić dodatkowe atrybuty do zachowania, ale w większości przypadków związanych z dostępem refleksyjnym lub 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 metoda zgłasza.

 Ten atrybut nie jest zwykle używany w przypadku aplikacji. W przypadku autorów bibliotek nie jest on zwykle używany w regułach przechowywania danych użytkowników, ale często stosuje się go 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 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 w przypadku odbicia w 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 działania.

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.