Optimierung für Bibliotheksautoren

Als Bibliotheksautor sollten Sie dafür sorgen, dass App-Entwickler Ihre Bibliothek ganz einfach in ihre App einbinden können und dabei die Qualität der Nutzererfahrung nicht beeinträchtigt wird. Sie sollten dafür sorgen, dass Ihre Bibliothek ohne zusätzliche Einrichtung mit der Android-Optimierung kompatibel ist, oder dokumentieren, dass die Bibliothek möglicherweise nicht für die Verwendung auf Android-Geräten geeignet ist.

Diese Dokumentation richtet sich an Entwickler veröffentlichter Bibliotheken, kann aber auch für Entwickler interner Bibliotheksmodule in einer großen, modularen App nützlich sein.

Wenn Sie App-Entwickler sind und mehr über die Optimierung Ihrer Android-App erfahren möchten, lesen Sie den Hilfeartikel App-Optimierung aktivieren. Informationen dazu, welche Bibliotheken geeignet sind, finden Sie unter Bibliotheken mit Bedacht auswählen.

codegen anstelle von reflection verwenden

Verwenden Sie nach Möglichkeit die Codegenerierung (codegen) anstelle der Reflection. Codegen und Reflection sind gängige Ansätze, um bei der Programmierung Boilerplate-Code zu vermeiden. Codegen ist jedoch mit einem App-Optimierer wie R8 besser kompatibel:

  • Mit codegen wird Code während des Build-Prozesses analysiert und geändert. Da nach der Kompilierungszeit keine größeren Änderungen mehr vorgenommen werden, weiß der Optimierer, welcher Code letztendlich benötigt wird und was sicher entfernt werden kann.
  • Bei der Reflection wird Code zur Laufzeit analysiert und manipuliert. Da der Code erst bei der Ausführung endgültig festgelegt wird, weiß der Optimierer nicht, welcher Code sicher entfernt werden kann. Es wird wahrscheinlich Code entfernt, der während der Laufzeit dynamisch durch Reflection verwendet wird und zu App-Abstürzen führt.

Viele moderne Bibliotheken verwenden Codegen statt Reflection. KSP ist ein gängiger Einstiegspunkt, der unter anderem von Room und Dagger2 verwendet wird.

Wann ist Nachdenken in Ordnung?

Wenn Sie Reflexionen verwenden müssen, sollten Sie nur eine der folgenden Optionen verwenden:

  • Bestimmte ausgerichtete Typen (bestimmte Schnittstellenimplementierer oder Unterklassen)
  • Code mit einer bestimmten Laufzeitanmerkung

Durch die Verwendung der Reflection auf diese Weise werden die Laufzeitkosten begrenzt und es ist möglich, zielgerichtete Regeln für die Aufbewahrung von Daten zu schreiben.

Diese spezifische und gezielte Form der Reflexion ist ein Muster, das sowohl im Android-Framework (z. B. beim Aufblähen von Aktivitäten, Ansichten und Drawables) als auch in AndroidX-Bibliotheken (z. B. beim Erstellen von WorkManager-ListenableWorkers oder RoomDatabases) zu sehen ist. Im Gegensatz dazu ist die offene Reflexion von Gson nicht für die Verwendung in Android-Apps geeignet.

Regeln für die Aufbewahrung von Inhalten für den Nutzer schreiben

Bibliotheken sollten „Verbraucher“-Aufbewahrungsregeln enthalten, die dasselbe Format wie App-Aufbewahrungsregeln verwenden. Diese Regeln werden in Bibliotheksartefakten (AARs oder JARs) gebündelt und bei der Optimierung von Android-Apps automatisch verwendet, wenn die Bibliothek verwendet wird.

AAR-Bibliotheken

Wenn Sie Verbraucherregeln für eine AAR-Bibliothek hinzufügen möchten, verwenden Sie die Option consumerProguardFiles im Build-Script des Android-Bibliotheksmoduls. Weitere Informationen finden Sie in unserer Anleitung zum Erstellen von Bibliotheksmodulen.

Kotlin

android {
    defaultConfig {
        consumerProguardFiles("consumer-proguard-rules.pro")
    }
    ...
}

Groovy

android {
    defaultConfig {
        consumerProguardFiles 'consumer-proguard-rules.pro'
    }
    ...
}

JAR-Bibliotheken

Wenn Sie Regeln mit Ihrer Kotlin-/Java-Bibliothek bündeln möchten, die als JAR-Datei bereitgestellt wird, legen Sie die Regelndatei mit einem beliebigen Dateinamen im Verzeichnis META-INF/proguard/ der endgültigen JAR-Datei ab. Wenn sich Ihr Code beispielsweise in <libraryroot>/src/main/kotlin befindet, legen Sie eine Datei mit Verbraucherregeln unter <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro ab. Die Regeln werden dann am richtigen Speicherort in der Ausgabe-JAR-Datei verpackt.

Prüfen Sie, ob das finale JAR-Archiv die Regeln korrekt bündelt. Dazu müssen sich die Regeln im Verzeichnis META-INF/proguard befinden.

Unterstützung verschiedener Komprimierungstools (erweitert)

Sie können Regeln auf bestimmte Schrumpfer (R8 oder ProGuard) sowie auf bestimmte Schrumpferversionen ausrichten. So kann Ihre Bibliothek optimal in Projekten mit neuen Shrinker-Versionen verwendet werden, während vorhandene Regeln weiterhin in Projekten mit älteren Shrinker-Versionen verwendet werden können.

Wenn Sie gezielte Schrumpfregeln angeben möchten, müssen Sie sie an bestimmten Stellen in einer AAR- oder JAR-Bibliothek einfügen, wie unten beschrieben.

In an AAR library:
    consumer-proguard-rules.pro (legacy location)
    classes.jar
    └── META-INF
        └── com.android.tools (targeted shrink rules location)
            ├── r8-from-<X>-upto-<Y>/<R8-rules-file>
            └── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>

In a JAR library:
    META-INF
    ├── proguard/<ProGuard-rules-file> (legacy location)
    └── com.android.tools (targeted shrink rules location)
        ├── r8-from-<X>-upto-<Y>/<R8-rules-file>
        └── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>

Das bedeutet, dass Regeln für die gezielte Verkleinerung im Verzeichnis META-INF/com.android.tools einer JAR-Datei oder im Verzeichnis META-INF/com.android.tools in classes.jar einer AAR-Datei gespeichert werden.

Unter diesem Verzeichnis können sich mehrere Verzeichnisse mit Namen im Format r8-from-<X>-upto-<Y> oder proguard-from-<X>-upto-<Y> befinden, die angeben, für welche Versionen der einzelnen Schrumpfer die Regeln in den Verzeichnissen geschrieben wurden. Die Teile „-from-<X>“ und „-upto-<Y>“ sind optional. Die Version <Y> ist ausschließlich und die Versionsbereiche müssen fortlaufend sein.

Beispiel: r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0 und r8-from-8.2.0 bilden eine gültige Reihe von Regeln für die gezielte Verkleinerung. Die Regeln im Verzeichnis r8-from-8.0.0-upto-8.2.0 werden von R8 ab Version 8.0.0 bis einschließlich Version 8.2.0 verwendet.

Anhand dieser Informationen wählt das Android Gradle-Plug-in die Regeln aus den entsprechenden R8-Verzeichnissen aus. Wenn für eine Bibliothek keine Regeln für die gezielte Verkleinerung angegeben sind, wählt das Android Gradle-Plug-in die Regeln aus den bisherigen Speicherorten aus (proguard.txt für eine AAR oder META-INF/proguard/<ProGuard-rules-file> für eine JAR).