Informacje o regułach przechowywania

Gdy włączysz optymalizację aplikacji z ustawieniami domyślnymi, R8 przeprowadzi rozległe optymalizacje, aby zmaksymalizować korzyści związane z wydajnością. R8 wprowadza istotne zmiany w kodzie, w tym zmienia nazwy, przenosi i usuwa klasy, pola i metody. Jeśli zauważysz, że te modyfikacje powodują błędy, musisz określić, których części kodu R8 nie powinien modyfikować, deklarując je w regułach zachowywania.

Typowe scenariusze, w których wymagane są reguły przechowywania

R8 identyfikuje i zachowuje wszystkie bezpośrednie wywołania w kodzie. R8 nie widzi jednak pośrednich zastosowań kodu, co może spowodować usunięcie kodu potrzebnego aplikacji i wywołać awarię. Za pomocą reguł keep możesz poinformować R8, aby zachowywał kod używany w sposób pośredni. Oto kilka typowych sytuacji, w których reguły przechowywania mogą być przydatne:

  • Kod, do którego uzyskano dostęp za pomocą odbicia: R8 nie może określić, kiedy klasy, pola lub metody są dostępne za pomocą odbicia. Na przykład R8 nie może zidentyfikować metody wyszukiwanej po nazwie za pomocą Class.getDeclaredMethod() ani adnotacji pobranej za pomocą Class.getAnnotation(). W takich przypadkach R8 może zmienić nazwy tych metod i adnotacji lub całkowicie je usunąć, co może spowodować błąd ClassNotFoundException lub NoSuchMethodException w czasie działania.
  • Kod wywoływany z interfejsu Java Native Interface (JNI): gdy kod natywny (C lub C++) wywołuje metodę Java lub Kotlin albo kod Java lub Kotlin wywołuje kod C++ za pomocą JNI, wywołanie jest oparte na dynamicznym wyszukiwaniu nazwy metody w ciągu znaków. R8 nie widzi wywołania metody opartego na dynamicznym ciągu znaków, więc jego optymalizacje mogą spowodować błędy w kodzie.

Nie jest to wyczerpująca lista scenariuszy, w których wymagane są reguły przechowywania, ale obejmuje ona większość przypadków, w których mogą być one potrzebne.

Dodawanie reguł przechowywania do aplikacji

Reguły należy dodać do pliku proguard-rules.pro znajdującego się w katalogu głównym modułu aplikacji. Plik może już tam być, ale jeśli go nie ma, utwórz go. Aby zastosować reguły w pliku, musisz zadeklarować go w pliku build.gradle.kts (lub build.gradle) na poziomie modułu, jak pokazano w tym kodzie:

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile("proguard-android-optimize.txt"),

                // File with your custom rules
                "proguard-rules.pro"
            )
           // ...
        }
    }
    // ...
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile('proguard-android-optimize.txt'),

                // File with your custom rules.
                'proguard-rules.pro'
            )
           // ...
        }
    }
    // ...
}

Domyślnie plik kompilacji zawiera też plik proguard-android-optimize.txt. Ten plik zawiera reguły wymagane w większości projektów na Androida, więc powinien pozostać w pliku kompilacji. Ten plik jest oparty na pliku proguard-common.txt i zawiera te same treści.

Większe aplikacje zwykle mają kod w wielu modułach biblioteki. W takich przypadkach często lepiej jest umieścić reguły zachowywania obok kodu, do którego się odnoszą, w odpowiednim module biblioteki. Kluczowa różnica w utrzymywaniu reguł zachowywania w przypadku bibliotek polega na sposobie deklarowania tych reguł w pliku build.gradle.kts (lub build.gradle) modułu biblioteki. Więcej informacji znajdziesz w artykule Optymalizacja dla autorów bibliotek.

Dodawanie reguły przechowywania

Gdy dodajesz reguły przechowywania, możesz uwzględnić opcje globalne, a także zdefiniować własne reguły przechowywania.

  • Opcje globalne: opcje globalne to ogólne dyrektywy, które wpływają na sposób działania R8 w całym kodzie. Więcej informacji znajdziesz w sekcji Opcje globalne.
  • Reguły zachowywania: reguły zachowywania muszą być starannie zaprojektowane, aby zapewnić odpowiednią równowagę między maksymalizacją optymalizacji kodu a unikaniem przypadkowego uszkodzenia aplikacji. Aby poznać składnię własnych reguł zachowywania, zapoznaj się z sekcją Składnia reguł zachowywania.

Zasady dotyczące autorów bibliotek

Po zapoznaniu się z opcjami globalnymi i składnią zasad zachowywania zapoznaj się z artykułem Optymalizacja dla autorów bibliotek, aby dowiedzieć się więcej.