Wenn Sie die App-Optimierung aktivieren, ist das Standardverhalten des Optimierers für verschiedene Versionen von R8 unterschiedlich.
- Mit der aktualisierten DSL, die ab AGP 9.3 und höher verfügbar ist, ist die Ressourcenverkleinerung standardmäßig aktiviert, wenn die Optimierung aktiviert ist. Die alte DSL, für die Code- und Ressourcenoptimierung separat aktiviert werden muss, wird weiterhin unterstützt.
Bei Versionen vor AGP 9.3 weist die Einstellung
isShrinkResources = trueden Optimierer an, nicht verwendete Ressourcen zu entfernen, wodurch die Größe Ihrer App verringert wird. Die Ressourcenreduzierung funktioniert nur in Verbindung mit der Code-Reduzierung. Wenn Sie also Ressourcen optimieren, legen Sie auchisMinifyEnabled = truefest.
AGP 9.3+ (Kotlin)
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
AGP 9.3+ (Groovy)
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
Alte DSL (Kotlin)
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
...
}
}
Alte DSL (Groovy)
buildTypes {
release {
minifyEnabled = true
shrinkResources = true
...
}
}
Wenn Sie bestimmte Ressourcen beibehalten oder verwerfen möchten, erstellen Sie in den Projektressourcen eine XML-Datei vom Typ keep, z. B. res/raw/my.package.keep.xml. Die Datei zum Beibehalten hat die folgenden Komponenten:
<resources>-Tag: Enthält alle untergeordneten Ressourcenelemente und keep/discard-Attribute.- Attribut
tools:keep: Akzeptiert eine durch Kommas getrennte Liste von Ressourcennamen, die Ressourcen angeben, die beibehalten werden sollen. - Attribut
tools:discard: Akzeptiert eine durch Kommas getrennte Liste von Ressourcennamen, die zu verwerfende Ressourcen identifizieren.
Verwenden Sie das Sternchen als Platzhalter, um auf mehrere Ressourcen im selben Ordner zu verweisen, z. B.:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
tools:discard="@layout/unused2" />
Die Angabe, welche Ressourcen verworfen werden sollen, mag überflüssig erscheinen, da Sie sie stattdessen auch löschen könnten. Das Verwerfen von Ressourcen kann jedoch bei der Verwendung von Build-Varianten nützlich sein.
Auf bestimmte Build-Varianten ausrichten
Wenn Sie Ressourcen nur in einigen Build-Varianten entfernen möchten, legen Sie alle Ressourcen in das gemeinsame Projektverzeichnis und erstellen Sie dann für jede Build-Variante eine andere my.package.build.variant.keep.xml-Datei im Ressourcenverzeichnis der Variante. Geben Sie in der Keep-Datei manuell Ressourcen an, die entfernt werden sollen, wenn eine bestimmte Ressource im Code verwendet wird (und daher nicht vom Shrinker entfernt wird), Sie aber wissen, dass sie für die jeweilige Build-Variante nicht verwendet wird.
Nicht verwendete alternative Ressourcen entfernen
Der Optimierer entfernt nur Ressourcen, auf die im App-Code nicht verwiesen wird. Das bedeutet, dass er keine alternativen Ressourcen für verschiedene Gerätekonfigurationen entfernt.
Verwenden Sie die Android Gradle-Eigenschaft resConfigs in der build.gradle-Datei des App-Moduls, um alternative Ressourcendateien zu entfernen, die Ihre App nicht benötigt.
Wenn Sie beispielsweise eine Bibliothek verwenden, die Sprachressourcen enthält (z. B. Google Play-Dienste), enthält Ihre App alle übersetzten Sprachstrings für die Meldungen in diesen Bibliotheken, unabhängig davon, ob der Rest Ihrer App in dieselben Sprachen übersetzt ist. Wenn Sie nur die Sprachen beibehalten möchten, die Ihre App offiziell unterstützt, geben Sie diese Sprachen mit dem Attribut resConfigs an.
Alle Ressourcen für nicht angegebene Sprachen werden entfernt.
Die folgenden Snippets zeigen, wie Sie Ihre Sprachressourcen auf Englisch und Französisch beschränken:
android {
defaultConfig {
...
resourceConfigurations.addAll(listOf("en", "fr"))
}
}
oder
android {
defaultConfig {
...
resConfigs "en", "fr"
}
}
Wenn Sie eine App im AAB-Format (Android App Bundle) veröffentlichen, werden beim Installieren der App durch einen Nutzer standardmäßig nur die auf dem Gerät des Nutzers konfigurierten Sprachen heruntergeladen. Entsprechend werden nur Ressourcen, die der Bildschirmdichte des Geräts entsprechen, und native Bibliotheken, die der ABI des Geräts entsprechen, in den Download aufgenommen. Weitere Informationen finden Sie unter Konfigurations-APKs reaktivieren oder deaktivieren.
Bei älteren Apps, die mit APKs veröffentlicht werden (vor August 2021 erstellt), können Sie die Bildschirmdichte oder ABI-Ressourcen anpassen, die in Ihr APK aufgenommen werden sollen, indem Sie mehrere APKs erstellen, die auf verschiedene Gerätekonfigurationen ausgerichtet sind.
Konflikte beim Zusammenführen von Ressourcen vermeiden
Standardmäßig führt das Android-Gradle-Plug-in (AGP) Ressourcen mit identischen Namen zusammen, z. B. Drawables mit demselben Namen, die sich in verschiedenen Ressourcenordnern befinden.
Dieses Verhalten wird nicht durch die shrinkResources-Eigenschaft gesteuert und kann nicht deaktiviert werden, da es erforderlich ist, um Fehler zu vermeiden, wenn mehrere Ressourcen den Namen haben, auf den sich Ihr Code bezieht.
Das Zusammenführen von Ressourcen erfolgt nur, wenn zwei oder mehr Dateien einen identischen Ressourcennamen, ‑typ und ‑qualifier haben. AGP wählt die Datei aus, die es als beste Wahl unter den Duplikaten identifiziert (basierend auf einer unten beschriebenen Prioritätsreihenfolge), und übergibt nur diese Ressource an AAPT zur Verteilung im endgültigen Build-Artefakt.
AGP sucht an den folgenden Stellen nach doppelten Ressourcen:
- Hauptressourcen, die mit dem Haupt-Source-Set verknüpft sind und sich in der Regel in
src/main/res/befinden - Varianten-Overlays aus dem Build-Typ und den Build-Varianten
- Abhängigkeiten von Library-Projekten
AGP führt doppelte Ressourcen in der folgenden kaskadierenden Prioritätsreihenfolge zusammen:
Wenn beispielsweise eine doppelte Ressource sowohl in Ihren Hauptressourcen als auch in einer Build-Variante vorhanden ist, wählt Gradle die Ressource in der Build-Variante aus.
Wenn identische Ressourcen im selben Source-Set vorhanden sind, kann Gradle sie nicht zusammenführen und gibt einen Fehler beim Zusammenführen von Ressourcen aus. Dies kann passieren, wenn Sie in der Datei build.gradle Ihres Moduls sourceSet mehrere Quellsätze definieren, z. B. wenn sowohl src/main/res/ als auch src/main/res2/ identische Ressourcen enthalten.
Probleme mit der Entfernung von Ressourcen beheben
Wenn Sie Ressourcen verkleinern, wird im Fenster Build eine Zusammenfassung der aus der App entfernten Ressourcen angezeigt. Wenn Sie links im Fenster auf Ansicht umschalten klicken, wird eine detaillierte Textausgabe von Gradle angezeigt. Beispiel:
:android:shrinkDebugResources
Removed unused resources: Resource data reduced from 2570KB to 1711KB: Removed 33%
:android:validateDebugSigning
Gradle erstellt außerdem eine Diagnosedatei mit dem Namen resources.txt in <module-name>/build/outputs/mapping/release/ (demselben Ordner wie die ProGuard-Ausgabedateien). Die Datei enthält Details dazu, welche Ressourcen auf andere Ressourcen verweisen und welche Ressourcen verwendet oder entfernt werden.
Wenn Sie beispielsweise herausfinden möchten, warum @drawable/ic_plus_anim_016 weiterhin in Ihrer App enthalten ist, öffnen Sie die Datei resources.txt und suchen Sie nach diesem Dateinamen. Möglicherweise wird darauf von einer anderen Ressource verwiesen:
16:25:48.005 [QUIET] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true
16:25:48.009 [QUIET] [system.out] @drawable/ic_plus_anim_016
Sie müssen jetzt wissen, warum @drawable/add_schedule_fab_icon_anim erreichbar ist. Wenn Sie nach oben suchen, finden Sie die Ressource in resources.txt unter der Überschrift Die erreichbaren Stammressourcen sind:.
Das bedeutet, dass es einen Codeverweis auf add_schedule_fab_icon_anim gibt, d. h., die R.drawable-ID wurde im erreichbaren Code gefunden.
Sofern Sie keine strenge Prüfung verwenden, können Ressourcen-IDs als erreichbar markiert werden, wenn es Stringkonstanten gibt, die möglicherweise zum Erstellen von Ressourcennamen für dynamisch geladene Ressourcen verwendet werden. Wenn Sie in diesem Fall in der Build-Ausgabe nach dem Ressourcennamen suchen, finden Sie möglicherweise eine Meldung wie diese:
10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
used because its format-string matches string pool constant ic_plus_anim_%1$d.
Wenn Sie einen dieser Strings sehen und sicher sind, dass er nicht zum dynamischen Laden der angegebenen Ressource verwendet wird, verwenden Sie das Attribut tools:discard in Ihrer Keep-Datei, um das Build-System anzuweisen, die Ressource zu entfernen.