Stosuj sprawdzone metody

Podczas pracy z regułami przechowywania ważne jest, aby osiągnąć odpowiedni poziom szczegółowości, który zapewni Ci korzyści przy zachowaniu dotychczasowego działania aplikacji. W sekcjach poniżej znajdziesz informacje o dobrych wzorcach i rzeczach, których należy unikać w przypadku reguł przechowywania.

Dobre wzorce w regułach przechowywania

Dobrze zdefiniowane reguły przechowywania są jak najbardziej szczegółowe i odpowiadają tym wzorcom:

  • W specyfikacji klasy zawsze podawaj konkretną klasę, klasę bazową lub klasę z adnotacjami, jeśli to możliwe, jak pokazano w tych przykładach:

    -keepclassmembers class com.example.MyClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers ** extends com.example.MyBaseClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers @com.example.MyAnnotation class ** {
      void someSpecificMethod();
    }
    
  • W miarę możliwości używaj adnotacji w kodzie źródłowym, a następnie kieruj na nie reguły zachowywania. Tworzy to jasne, wyraźne powiązanie między kodem a regułami, które go zachowują, dzięki czemu konfiguracja jest bardziej niezawodna, łatwiejsza do zrozumienia i mniej podatna na uszkodzenia w przypadku zmian w kodzie.

    Na przykład ten fragment kodu pokazuje, jak zachować klasę MyClass oraz inne klasy oznaczone adnotacją @com.example.DisplayComponent:

    // In the source code
    @com.example.DisplayComponent
    class MyClass { /* ... */ }
    
    // In the keep rules
    -keep @com.example.DisplayComponent class * {*;}
    

    Zalecamy nadawanie adnotacjom nazw, które dostarczają istotnych informacji o tym, dlaczego fragmenty kodu są zachowywane. Na przykład użyj @DisplayComponent w przypadku aplikacji, w której komponenty wyświetlania wymagają zachowania niektórych części.

  • W miarę możliwości należy zadeklarować specyfikację elementu i odwoływać się tylko do tych części klasy, które muszą być zachowane, aby aplikacja działała. Nie zalecamy stosowania reguły do całej klasy przez zdefiniowanie opcjonalnego zakresu elementu jako { *; }, chyba że jest to bezwzględnie konieczne.

    -keepclassmembers com.example.MyClass {
      void someSpecificMethod();
      void @com.example.MyAnnotation *;
    }
    
  • Jeśli używasz repackageclassesopcji globalnej, nie podawaj opcjonalnej nazwy pakietu. Dzięki temu pliki DEX są mniejsze, ponieważ w nazwach klas po ponownym spakowaniu pomijany jest prefiks pakietu.

  • Zachowaj reguły zachowywania dla wszystkich elementów, do których uzyskano dostęp przez odbicie. Nawet jeśli takie elementy są zachowywane przez R8 bez wyraźnych reguł zachowywania, utrzymywanie rzeczywistych reguł jest kluczowe, ponieważ przyszłe zmiany w kodzie mogą spowodować, że R8 przestanie zachowywać te elementy.

Jeśli nie możesz przestrzegać tych wytycznych, możesz tymczasowo odizolować kod, który ma zostać zachowany, w osobnym pakiecie i zastosować do niego regułę zachowywania. Nie jest to jednak rozwiązanie długoterminowe. Więcej informacji znajdziesz w artykule Stopniowe wprowadzanie optymalizacji. Aby użyć reguły przechowywania pakietu, zdefiniuj ją tak jak w tym przykładzie:

-keepclassmembers class com.example.pkg.** { *; }

Czego warto unikać

Składnia reguły zachowywania ma wiele opcji, ale w przypadku mierzalnych korzyści związanych ze zrównoważonym rozwojem nie zalecamy używania tych elementów:

  • Nie używaj reguł przechowywania obejmujących całe pakiety, np. -keep class com.example.pkg.** { *; }, przez długi czas. Można ich tymczasowo używać do rozwiązywania problemów podczas konfigurowania R8. Więcej informacji znajdziesz w artykule Ograniczanie zakresu optymalizacji. Ogólnie rzecz biorąc, zachowaj ostrożność w przypadku symboli wieloznacznych – upewnij się, że zachowujesz tylko potrzebny kod.
  • Jeśli to możliwe, unikaj bibliotek, które sugerują kopiowanie i wklejanie reguł zachowywania, zwłaszcza reguł zachowywania dotyczących całego pakietu. Biblioteki zaprojektowane z myślą o dobrej wydajności na Androidzie powinny w miarę możliwości unikać odbicia i w razie potrzeby osadzać reguły zachowywania.
  • Unikaj używania operatora negacji ! w regułach zachowywania, ponieważ możesz nieumyślnie zastosować regułę do niemal każdej klasy w aplikacji.

Jeśli nie możesz przestrzegać tych reguł, prawdopodobnie używasz wielu otwartych odbić i powinieneś ich unikać lub unikać biblioteki, która ich używa (patrz studium przypadku Gson).