Informacje o regułach przechowywania

Gdy włączysz optymalizację aplikacji z ustawieniami domyślnymi, R8 przeprowadzi optymalizację na dużą skalę, aby zmaksymalizować korzyści z wydajności. R8 wprowadza znaczące modyfikacje w kodzie, w tym zmianę nazw, przenoszenie i usuwanie klas, pól i metod. 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 wymagające reguł zachowywania

R8 identyfikuje i zachowuje wszystkie bezpośrednie wywołania w kodzie. Nie widzi jednak pośrednich zastosowań kodu, co może spowodować usunięcie kodu potrzebnego aplikacji i doprowadzić do awarii. Użyj reguł zachowywania, aby poinformować R8, że ma zachować taki pośrednio używany kod. Oto kilka typowych sytuacji, w których prawdopodobnie będziesz potrzebować reguł zachowywania:

  • Kod, do którego uzyskuje się 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 według nazwy 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 spowoduje wystąpienie w czasie działania wyjątku ClassNotFoundException lub NoSuchMethodException.
  • Kod wywoływany z interfejsu Java Native Interface (JNI): gdy kod natywny (C lub C++) wywołuje metodę Java lub Kotlin albo gdy kod Java lub Kotlin wywołuje kod C++ za pomocą JNI, wywołanie jest oparte na dynamicznym wyszukiwaniu nazwy metody. R8 nie widzi wywołania metody opartego na dynamicznym ciągu znaków, dlatego jego optymalizacje mogą spowodować uszkodzenie kodu.

To nie jest wyczerpująca lista scenariuszy, które wymagają reguł zachowywania, ale obejmuje ona większość przypadków, w których mogą być one potrzebne.

Jak dodać reguły zachowywania do aplikacji

Konfiguracja reguł zachowywania zależy od używanej wersji AGP.

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 konkretnym module biblioteki. Kluczowa różnica w utrzymywaniu reguł zachowywania w przypadku bibliotek polega na tym, jak deklarujesz te reguły w pliku modułu biblioteki build.gradle.kts (lub build.gradle). Więcej informacji znajdziesz w artykule Optymalizacja dla autorów bibliotek.

W przypadku AGP w wersji 9.3 lub nowszej

Dodaj reguły do pliku z sufiksem .keep w katalogu src/<variant>/keepRules. Na przykład src/main/keepRules/custom-rules.keep. Pamiętaj, że używanie zaktualizowanego DSL w przypadku AGP w wersji 9.3 lub nowszej umożliwia optymalizację kodu i zasobów oraz nie wymaga jawnego zdefiniowania domyślnego pliku reguł zachowywania Androida (proguard-android-optimize.txt), ponieważ jest on domyślnie uwzględniany, chyba że zostanie wyraźnie pominięty.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Dynamiczny

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Pomijanie domyślnych reguł zachowywania platformy Android (zaawansowane)

AGP udostępnia zestaw domyślnych reguł platformy Android. Aby pominąć te reguły w konfiguracji projektu i samodzielnie zarządzać wszystkimi regułami zachowywania, ustaw optimization.keepRules.includeDefault na false.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

Dynamiczny

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

Starszy DSL w przypadku AGP w wersji starszej niż 9.3

Dodaj reguły 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 na poziomie modułu build.gradle.kts (lub build.gradle).

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, dlatego należy go pozostawić w pliku kompilacji. Ten plik jest oparty na pliku proguard-common.txt i zawiera te same treści.

Starszy DSL (Kotlin)

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

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),
                ...
            )
        }
    }
}

Starszy DSL (Dynamiczny)

android {
    buildTypes {
        release {
            minifyEnabled = true
            shrinkResources = true

            // Default file with default optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
            ...
        }
    }
}

Dodawanie reguły zachowywania

Gdy dodajesz reguły zachowywania, możesz uwzględnić opcje globalne oraz zdefiniować własne reguły zachowywania.

  • Opcje globalne: opcje globalne to ogólne dyrektywy, które wpływają na sposób działania R8 w całej bazie kodu. Więcej informacji znajdziesz w artykule 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 dowiedzieć się, jak pisać reguły zachowywania, przeczytaj artykuł Dodawanie reguł zachowywania.

Reguły zachowywania dla autorów bibliotek

Po zapoznaniu się z opcjami globalnymi i składnią reguł zachowywania przeczytaj artykuł Optymalizacja dla autorów bibliotek, aby uzyskać więcej informacji.