In der modernen Android-Entwicklung ist es eine grundlegende Erwartung der Nutzer, dass Apps klein, schnell und sicher sind. Das primäre Tool des Android-Build-Systems, um dies zu erreichen, ist der R8-Optimierer . Dieser Compiler kümmert sich um das Entfernen von nicht verwendetem Code und Ressourcen zum Verkleinern, das Umbenennen oder Minimieren von Code sowie die Optimierung von Apps.
Die Aktivierung von R8 ist ein wichtiger Schritt bei der Vorbereitung einer App für die Veröffentlichung. Dazu müssen Entwickler jedoch Anleitungen in Form von „Keep-Regeln“ bereitstellen.
Nachdem Sie diesen Artikel gelesen haben, können Sie sich auf YouTube das Video zur Performance Spotlight Week ansehen, in dem es um das Aktivieren, Debuggen und Beheben von Problemen mit dem R8-Optimierer geht.
Warum sind Aufbewahrungsregeln erforderlich?
Die Notwendigkeit, Keep-Regeln zu schreiben, ergibt sich aus einem grundlegenden Konflikt: R8 ist ein Tool zur statischen Analyse, Android-Apps basieren jedoch häufig auf dynamischen Ausführungsmustern wie Reflection oder Aufrufen von und nach nativem Code über die JNI (Java Native Interface).
R8 erstellt ein Diagramm des verwendeten Codes, indem direkte Aufrufe analysiert werden. Wenn auf Code dynamisch zugegriffen wird, kann die statische Analyse von R8 das nicht vorhersagen. Der Code wird als nicht verwendet identifiziert und entfernt, was zu Laufzeitabstürzen führt.
Eine Keep-Regel ist eine explizite Anweisung an den R8-Compiler, die besagt: „Diese bestimmte Klasse, Methode oder dieses bestimmte Feld ist ein Einstiegspunkt, auf den zur Laufzeit dynamisch zugegriffen wird. Sie müssen sie beibehalten, auch wenn Sie keinen direkten Verweis darauf finden.“
Weitere Informationen zu Keep-Regeln finden Sie im offiziellen Leitfaden.
Regeln zum Beibehalten von Inhalten schreiben
Benutzerdefinierte Keep-Regeln für eine Anwendung werden in einer Textdatei geschrieben. Konventionsgemäß heißt diese Datei proguard-rules.pro und befindet sich im Stammverzeichnis des App- oder Bibliotheksmoduls. Diese Datei wird dann im Build-Typ release der Datei build.gradle.kts Ihres Moduls angegeben.
release {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}Die richtige Standarddatei verwenden
Mit der Methode getDefaultProguardFile wird ein Standardsatz von Regeln importiert, der vom Android SDK bereitgestellt wird. Wenn Sie die falsche Datei verwenden, ist Ihre App möglicherweise nicht optimiert. Verwenden Sie proguard-android-optimize.txt. Diese Datei enthält die Standard-Keep-Regeln für Standard-Android-Komponenten und aktiviert die Codeoptimierungen von R8. Die veraltete proguard-android.txt bietet nur die Keep-Regeln, nicht aber die Optimierungen von R8.
Da dies ein schwerwiegendes Leistungsproblem ist, warnen wir Entwickler ab dem Android Studio Narwhal 3 Feature Drop vor der Verwendung der falschen Datei. Ab dem Android Gradle-Plug-in 9.0 unterstützen wir die veraltete proguard-android.txt-Datei nicht mehr. Aktualisieren Sie daher auf die optimierte Version.
Regeln zum Beibehalten von Daten schreiben
Eine Aufbewahrungsregel besteht aus drei Hauptteilen:
- Eine Option wie
-keepoder-keepclassmembers - Optionale Modifikatoren wie
allowshrinking - Eine Klassenspezifikation, die den abzugleichenden Code definiert
Die vollständige Syntax und Beispiele finden Sie in der Anleitung zum Hinzufügen von Aufbewahrungsregeln.
Anti-Muster für „Beibehalten“-Regeln
Es ist wichtig, Best Practices, aber auch Anti-Patterns zu kennen. Diese Anti-Patterns entstehen oft durch Missverständnisse oder Abkürzungen bei der Fehlerbehebung und können sich katastrophal auf die Leistung eines Produktions-Builds auswirken.
Globale Optionen
Diese Flags sind globale Schalter, die niemals in einem Release-Build verwendet werden sollten. Sie sind nur für das vorübergehende Debugging vorgesehen, um ein Problem einzugrenzen.
Durch die Verwendung von -dontotptimize werden die Leistungsoptimierungen von R8 effektiv deaktiviert, was zu einer langsameren App führt.
Wenn Sie -dontobfuscate verwenden, deaktivieren Sie das Umbenennen. Wenn Sie -dontshrink verwenden, wird das Entfernen von nicht verwendetem Code deaktiviert. Beide globalen Regeln erhöhen die App-Größe.
Vermeiden Sie die Verwendung dieser globalen Flags in einer Produktionsumgebung, um die Leistung der App zu verbessern.
Zu allgemeine Aufbewahrungsregeln
Die einfachste Möglichkeit, die Vorteile von R8 zunichte zu machen, besteht darin, zu weit gefasste Keep-Regeln zu schreiben. Keep-Regeln wie die unten stehende weisen den R8-Optimizer an, keine Klasse in diesem Paket oder keines seiner Unterpakete zu verkleinern, zu verschleiern oder zu optimieren. Dadurch werden die Vorteile von R8 für das gesamte Paket vollständig zunichte gemacht. Versuchen Sie stattdessen, enge und spezifische Keep-Regeln zu schreiben.
-keep class com.example.package.** { *;} // WIDE KEEP RULES CAUSE PROBLEMSDer Inversionsoperator (!)
Der Inversionsoperator (!) ist eine leistungsstarke Möglichkeit, ein Paket aus einer Regel auszuschließen. So einfach ist es aber nicht. Schauen wir uns dieses Beispiel an:
-keep class !com.example.my_package.** { *; } // USE WITH CAUTIONSie denken vielleicht, dass diese Regel bedeutet, dass com.example.package keine Klassen enthalten darf. Tatsächlich bedeutet sie aber, dass com.example.package jede Klasse, Methode und Eigenschaft in der gesamten Anwendung enthalten darf, die nicht in com.example.package enthalten ist. Wenn Sie das überrascht, sollten Sie Ihre R8-Konfiguration auf Negationen prüfen.
Redundante Regeln für Android-Komponenten
Ein weiterer häufiger Fehler ist das manuelle Hinzufügen von Keep-Regeln für die Activities, Services oder BroadcastReceivers Ihrer App. Das ist nicht erforderlich. Die Standarddatei proguard-android-optimize.txt enthält bereits die relevanten Regeln, damit diese Standard-Android-Komponenten sofort funktionieren.
Viele Bibliotheken haben auch eigene Keep-Regeln. Sie sollten also keine eigenen Regeln für diese schreiben müssen. Wenn es ein Problem mit Keep-Regeln aus einer Bibliothek gibt, die Sie verwenden, wenden Sie sich am besten an den Autor der Bibliothek, um herauszufinden, woran es liegt.
Best Practices für Regeln
Nachdem Sie nun wissen, was Sie nicht tun sollten, sprechen wir über Best Practices.
Präzise Regeln für Google Notizen erstellen
Gute Keep-Regeln sollten so eingeschränkt und spezifisch wie möglich sein. Sie sollten nur das bewahren, was notwendig ist, damit R8 alles andere optimieren kann.
| Regel | Qualität |
|---|---|
| Niedrig:Behält ein gesamtes Paket und seine Unterpakete bei. |
| Niedrig:Behält eine gesamte Klasse bei, die wahrscheinlich noch zu breit ist. |
-keepclassmembers class com.example.MyClass {
private java.lang.String secretMessage;
public void onNativeEvent(java.lang.String);
} | Hoch:Nur relevante Methoden und Eigenschaften einer bestimmten Klasse werden beibehalten. |
Gemeinsame Vorfahren verwenden
Anstatt separate Keep-Regeln für mehrere verschiedene Datenmodelle zu schreiben, sollten Sie eine Regel schreiben, die auf eine gemeinsame Basisklasse oder ‑schnittstelle ausgerichtet ist. Die folgende Regel weist R8 an, alle Elemente von Klassen beizubehalten, die diese Schnittstelle implementieren. Sie ist sehr skalierbar.
# Keep all fields of any class that implements SerializableModel
-keepclassmembers class * implements com.example.models.SerializableModel {
<fields>;
}Mit Anmerkungen mehrere Klassen ansprechen
Erstellen Sie eine benutzerdefinierte Annotation (z.B. @Serialize) und verwenden Sie sie, um Klassen zu „taggen“, deren Felder beibehalten werden müssen. Dies ist ein weiteres übersichtliches, deklaratives und hochgradig skalierbares Muster. Sie können auch Keep-Regeln für bereits vorhandene Anmerkungen aus Frameworks erstellen, die Sie verwenden.
# Keep all fields of any class annotated with @Serialize
-keepclassmembers class * {
@com.example.annotations.Serialize <fields>;
}Die richtige Keep-Option auswählen
Die Option „Beibehalten“ ist der wichtigste Teil der Regel. Wenn Sie die falsche Option auswählen, kann die Optimierung unnötigerweise deaktiviert werden.
| Option „Behalten“ | Funktionsweise |
-keep | Verhindert, dass die Klasse und die in der Deklaration erwähnten Mitglieder entfernt oder umbenannt werden. |
-keepclassmembers | Verhindert, dass die angegebenen Mitglieder entfernt oder umbenannt werden. Der Kurs selbst kann jedoch entfernt werden, aber nur bei Kursen, die nicht anderweitig entfernt werden. |
-keepclasseswithmembers | Kombination: Die Klasse und ihre Mitglieder werden beibehalten, nur wenn alle angegebenen Mitglieder vorhanden sind. |
Weitere Informationen zur Option „Beibehalten“ finden Sie in unserer Dokumentation zu den Beibehalten-Optionen.
Optimierung mit Modifikatoren zulassen
Modifizierer wie allowshrinking und allowobfuscation lockern eine allgemeine -keep-Regel und geben R8 die Möglichkeit zur Optimierung zurück. Wenn Sie beispielsweise aufgrund einer Legacy-Bibliothek -keep für eine gesamte Klasse verwenden müssen, können Sie möglicherweise etwas Optimierung zurückgewinnen, indem Sie das Verkleinern und Verschleiern zulassen:
# Keep this class, but allow R8 to remove it if it's unused and allow R8 to rename it. -keep,allowshrinking,allowobfuscation class com.example.LegacyClass
Globale Optionen für zusätzliche Optimierung hinzufügen
Neben Keep-Regeln können Sie Ihrer R8-Konfigurationsdatei globale Flags hinzufügen, um noch mehr Optimierung zu ermöglichen.
-repackageclasses ist eine leistungsstarke Option, mit der R8 angewiesen wird, alle verschleierten Klassen in ein einzelnes Paket zu verschieben. Dadurch wird in der DEX-Datei viel Speicherplatz gespart, da redundante Paketnamensstrings entfernt werden.
-allowaccessmodification ermöglicht R8, den Zugriff zu erweitern (z.B. von private zu public), um aggressiveres Inlining zu ermöglichen. Diese Funktion ist jetzt standardmäßig aktiviert, wenn Sie proguard-android-optimize.txt verwenden.
Warnung:Bibliotheksautoren dürfen diese globalen Optimierungsflags niemals ihren Consumer-Regeln hinzufügen, da sie dann auf die gesamte App angewendet werden.
Um das noch deutlicher zu machen, werden in Version 9.0 des Android-Gradle-Plug-ins globale Optimierungs-Flags aus Bibliotheken ignoriert.
Best Practices für Bibliotheken
Jede Android-App verwendet Bibliotheken. Sehen wir uns also Best Practices für Bibliotheken an.
Für Entwickler von Bibliotheken
Wenn in Ihrer Bibliothek Reflection oder JNI verwendet wird, müssen Sie den Nutzern die erforderlichen Keep-Regeln zur Verfügung stellen. Diese Regeln werden in einer consumer-rules.pro-Datei platziert, die dann automatisch in die AAR-Datei der Bibliothek eingebunden wird.
android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
...
}Für Nutzer der Bibliothek
Problematische Aufbewahrungsregeln herausfiltern
Wenn Sie eine Bibliothek verwenden müssen, die problematische Keep-Regeln enthält, können Sie sie ab AGP 9.0 in Ihrer build.gradle.kts-Datei herausfiltern. Dadurch wird R8 angewiesen, die Regeln einer bestimmten Abhängigkeit zu ignorieren.
release {
optimization.keepRules {
// Ignore all consumer rules from this specific library
it.ignoreFrom("com.somelibrary:somelibrary")
}
}Die beste Aufbewahrungsregel ist keine Aufbewahrungsregel
Die ultimative R8-Konfigurationsstrategie besteht darin, Keep-Regeln überflüssig zu machen. Bei vielen Apps kann dies erreicht werden, indem moderne Bibliotheken ausgewählt werden, die Codegenerierung gegenüber der Reflektion bevorzugen. Durch die Codegenerierung kann der Optimierer leichter ermitteln, welcher Code zur Laufzeit tatsächlich verwendet wird und welcher Code entfernt werden kann. Da keine dynamische Reflektion verwendet wird, gibt es auch keine „versteckten“ Einstiegspunkte. Daher sind keine Keep-Regeln erforderlich. Wenn Sie eine neue Bibliothek auswählen, sollten Sie immer eine Lösung bevorzugen, die Codegenerierung anstelle von Reflection verwendet.
Weitere Informationen zum Auswählen von Bibliotheken finden Sie unter Bibliothek sorgfältig auswählen.
Debugging und Fehlerbehebung bei der R8-Konfiguration
Wenn R8 Code entfernt, der hätte beibehalten werden sollen, oder Ihre APK-Datei größer als erwartet ist, können Sie das Problem mit diesen Tools diagnostizieren.
Doppelte und globale Aufbewahrungsregeln finden
Da R8 Regeln aus Dutzenden von Quellen zusammenführt, ist es schwierig, das „finale“ Regelset zu ermitteln. Wenn Sie dieses Flag in Ihre proguard-rules.pro-Datei einfügen, wird ein vollständiger Bericht generiert:
# Outputs the final, merged set of rules to the specified file -printconfiguration build/outputs/logs/configuration.txt
Sie können in dieser Datei nach redundanten Regeln suchen oder eine problematische Regel (z. B. -dontoptimize) auf die spezifische Bibliothek zurückführen, in der sie enthalten ist.
Frage R8: Warum behältst du das?
Wenn eine Klasse, die entfernt werden sollte, weiterhin in Ihrer App vorhanden ist, kann R8 Ihnen den Grund dafür nennen. Fügen Sie einfach diese Regel hinzu:
# Asks R8 to explain why it's keeping a specific class class com.example.MyUnusedClass -whyareyoukeeping
Während des Builds gibt R8 die genaue Kette von Referenzen aus, die dazu geführt hat, dass die Klasse beibehalten wurde. So können Sie die Referenz nachvollziehen und Ihre Regeln anpassen.
Eine vollständige Anleitung finden Sie im Abschnitt Fehlerbehebung bei R8.
Weiteres Vorgehen
R8 ist ein leistungsstarkes Tool zur Verbesserung der Leistung von Android-Apps. Die Effektivität hängt davon ab, dass die Funktionsweise als Engine für statische Analysen richtig verstanden wird.
Wenn Sie spezifische Regeln auf Mitgliedsebene schreiben, Vorfahren und Anmerkungen verwenden und die richtigen Keep-Optionen sorgfältig auswählen, können Sie genau das beibehalten, was erforderlich ist. Die fortschrittlichste Methode besteht darin, Regeln ganz zu vermeiden, indem Sie moderne, auf Codegenerierung basierende Bibliotheken anstelle ihrer auf Reflexion basierenden Vorgänger verwenden.
Sehen Sie sich das heutige Spotlight Week-Video auf YouTube an und machen Sie mit unserer R8-Challenge weiter. Verwenden Sie #optimizationEnabled für alle Fragen zur Aktivierung oder Fehlerbehebung von R8. Wir sind für Sie da.
Überzeugen Sie sich selbst von den Vorteilen.
Wir empfehlen Ihnen, noch heute den vollständigen R8-Modus für Ihre App zu aktivieren.
- Folgen Sie unserem Entwicklerleitfaden, um loszulegen: App-Optimierung aktivieren.
- Prüfen Sie, ob Sie noch
proguard-android.txtverwenden, und ersetzen Sie es durchproguard-android-optimize.txt. - Messen Sie dann die Auswirkungen. Spüren Sie nicht nur den Unterschied, sondern bestätigen Sie ihn. Messen Sie die Leistungssteigerungen, indem Sie den Code aus unserer Macrobenchmark-Beispiel-App auf GitHub anpassen, um die Startzeiten vor und nach der Änderung zu messen.
Wir sind zuversichtlich, dass sich die Leistung Ihrer App dadurch deutlich verbessern wird.
Verwende den Social-Tag #AskAndroid, um deine Fragen zu stellen. Unsere Experten beantworten deine Fragen im Laufe der Woche.
Morgen geht es weiter mit Profil-basierter Optimierung mit Baseline- und Startup-Profilen. Außerdem erfahrt ihr, wie sich die Rendering-Leistung von Compose in den letzten Releases verbessert hat, und erhaltet Tipps zur Leistung bei Hintergrundaufgaben.
Weiterlesen
-
Produktneuheiten
Auf der Google I/O werden jedes Jahr neue Ankündigungen und Ressourcen für Ökosysteme und Produkte, einschließlich der Android-Entwicklung, vorgestellt. Da sich die Entwicklung hin zu KI- und Agent-basierten Tools verschiebt, haben wir unser Angebot erweitert, um Sie bei der Entwicklung für Android besser zu unterstützen.
Simona Milanovic • Lesezeit: 2 Minuten
-
Produktneuheiten
Auf der Google I/O 2026 haben wir gezeigt, wie Sie mit den neuesten Entwicklungen im Android-Ökosystem die Qualität Ihrer App steigern und gleichzeitig die Entwicklungseffizienz maximieren können.
Ataul Munim • Lesezeit: 3 Minuten
-
Produktneuheiten
Auf der Google I/O 2026 haben wir vorgestellt, wie sich Android von einem Betriebssystem zu einem intelligenten System entwickelt. Außerdem haben wir gezeigt, wie Sie intelligente Funktionen nativ mit dem System entwickeln und die Leistungsfähigkeit von Google AI in Ihre Apps einbinden können.
Jingyu Shi • Lesezeit: 2 Minuten
Auf dem Laufenden bleiben
Lassen Sie sich Woche für Woche die neuesten Informationen zur Android-Entwicklung zusenden.