Beibehaltungsregeln hinzufügen

Wenn Sie die App-Optimierung mit den Standardeinstellungen aktivieren, führt R8 umfangreiche Optimierungen durch, um die Leistung zu maximieren. R8 führt erhebliche Änderungen am Code durch, einschließlich Umbenennen, Verschieben und Entfernen von Klassenfeldern und ‑methoden. Wenn dadurch Fehler auftreten, müssen Sie angeben, welche Teile des Codes unverändert bleiben sollen. Dazu schreiben Sie keep rules.

In den folgenden Fällen kann R8 Code fälschlicherweise entfernen oder ändern:

  • Reflection: Code, auf den über Reflection zugegriffen wird, z. B. mit Class.forName() oder Method.invoke(). R8 kann in der Regel nicht erkennen, auf welche Klassen oder Methoden auf diese Weise zugegriffen wird.
  • Serialization: Klassen oder Felder, die für die Serialization und Deserialization erforderlich sind, werden von R8 möglicherweise als nicht verwendet eingestuft. Dies ist eine weitere Form der Reflection.
  • Java Native Interface (JNI): Java-Methoden, die aus nativem Code aufgerufen werden. R8 analysiert den nativen Code nicht, um zu sehen, was er möglicherweise in Java zurückruft.

Auf dieser Seite erfahren Sie, wie Sie den Umfang der Optimierungen von R8 einschränken. Informationen dazu, wie Sie anpassen können, welche Ressourcen aufbewahrt werden, finden Sie unter Aufbewahrungsregeln für Ressourcen hinzufügen.

Speicherregeln hinzufügen

Fügen Sie Ihre Regeln einer proguard-rules.pro-Datei im Stammverzeichnis des Moduls hinzu. Die Datei ist möglicherweise bereits vorhanden. Falls nicht, erstellen Sie sie. Wenn Sie die Regeln in der Datei anwenden möchten, müssen Sie die Datei in Ihrer build.gradle.kts- oder build.gradle-Datei auf Modulebene deklarieren, wie im folgenden Code gezeigt:

Kotlin

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

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

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

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true

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

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

Standardmäßig enthält Ihr Build-Script auch die Datei proguard-android-optimize.txt. Diese Datei enthält Regeln, die für die meisten Android-Projekte erforderlich sind. Sie sollten sie daher im Build-Script belassen.

Regeln für „Zu behalten“ schreiben

Während der App-Kompilierung erkennt R8, welcher Code in einer App beibehalten werden muss. Dazu wird der Aufrufgraph Ihrer App analysiert, der bei den Manifesteinträgen (z. B. Ihren Aktivitäten oder Diensten) beginnt und jeden App- und Bibliotheksfunktionsaufruf nachverfolgt. R8 entfernt Code, auf den nicht direkt auf diese Weise verwiesen wird. Dies kann zu Problemen führen, wenn ausgeführter Code nicht Teil dieses Graphen ist, z. B. Code, der durch Reflection aufgerufen wird. Wenn Sie eigene Regeln zum Beibehalten von Code schreiben, können Sie R8 über Code informieren, der in der App verbleiben muss.

Wenn Sie eine Beibehaltungsregel hinzufügen möchten, fügen Sie der Datei proguard-rules.pro eine -keep-Zeile hinzu.

Regelsyntax beibehalten

Die Regeln für die Aufbewahrung von Daten haben im Allgemeinen folgendes Format:

-<KeepOption> [OptionalModifier,...] <ClassSpecification> [{ OptionalMemberSpecification }]

Wenn Sie beispielsweise eine bestimmte Klasse und alle zugehörigen Mitglieder beibehalten möchten, verwenden Sie Folgendes:

-keep class com.myapp.MyClass { *; }

Weitere Beispiele finden Sie im Beispielbereich.

Die Komponenten der Regel „Beibehalten“ haben folgende Funktionen:

  • Mit <KeepOption> können Sie angeben, welche Aspekte einer Klasse beibehalten werden sollen:

    Option „Beibehalten“ Beschreibung

    -keep

    Bewahren Sie die Klasse und die in [{ OptionalMemberSpecification }] aufgeführten Mitglieder auf.

    -keepclassmembers

    Optimieren der Klasse zulassen. Wenn die Klasse beibehalten wird, werden auch die in [{ OptionalMemberSpecification }] aufgeführten Mitglieder beibehalten.

    -keepnames

    Erlauben Sie das Entfernen von Klassen und Mitgliedern, aber verschleiern oder ändern Sie sie nicht auf andere Weise.

    -keepclassmembernames

    Erlauben Sie das Entfernen von Kursen und Mitgliedern, aber verschleiern oder ändern Sie Mitglieder nicht auf andere Weise.

    -keepclasseswithmembers

    Es werden keine Klassen entfernt oder unkenntlich gemacht, wenn Mitglieder mit dem angegebenen Muster übereinstimmen.

    Wir empfehlen, hauptsächlich -keepclassmembers zu verwenden, da damit die meisten Optimierungen möglich sind, und bei Bedarf -keepnames. -keep ermöglicht keine Optimierungen. Verwenden Sie sie daher sparsam.

  • Mit [OptionalModifier],...] können Sie null oder mehr Java-Modifizierer einer Klasse auflisten, z. B. public oder final.

  • Mit <ClassSpecification> können Sie angeben, auf welche Klasse (oder welche Superklasse oder implementierte Schnittstelle) die Beibehaltungsregel angewendet werden soll. Im einfachsten Fall ist dies eine vollständig qualifizierte Klasse.

  • Mit [{ OptionalMemberSpecification }] können Sie das Beibehaltensverhalten auf Klassen und Methoden beschränken, die bestimmten Mustern entsprechen. Dies wird in den meisten Regeln für das Behalten generell empfohlen, um zu verhindern, dass mehr als beabsichtigt aufbewahrt wird.

Beispiele für Regeln für „Beibehalten“

Hier sind einige Beispiele für gut gestaltete Regeln für das Behalten von Inhalten.

Unterklasse erstellen

Diese Keep-Regel ist in androidx.room:room-runtime verpackt, damit Datenbankkonstruktoren durch Reflexion instanziiert werden.

-keep class * extends androidx.room.RoomDatabase { void <init>(); }

Reflexion vom Android-Framework ObjectAnimator

Diese Keep-Regel ist in androidx.vectordrawable:vectordrawable-animated verpackt, damit ObjectAnimator Getter oder Setter aus nativem Code mit JNI aufrufen kann. Neuere Animationssysteme in Compose erfordern keine solchen Beibehaltungsregeln. Dies ist nur ein Beispiel für eine Regelstruktur.

-keepclassmembers class androidx.vectordrawable.graphics.drawable.VectorDrawableCompat$* {
   void set*(***);
   *** get*();
}

JNI-Registrierung

Diese Regel zum Beibehalten ist in androidx.graphics:graphics-path verpackt und wird verwendet, um native Methoden beizubehalten. Dies kann erforderlich sein, wenn Ihre Bibliothek native Methoden manuell bei env->RegisterNatives() registriert.

-keepclasseswithmembers class androidx.graphics.path.** {
    native <methods>;
}