d8
ist ein Befehlszeilentool, mit dem Android Studio und das Android-Gradle-Plug-in den Java-Bytecode Ihres Projekts in DEX-Bytecode kompilieren können, der auf Android-Geräten ausgeführt wird. Mit d8
können Sie die Sprachfunktionen von Java 8 im Anwendungscode verwenden.
d8
ist auch als eigenständiges Tool in Android Build Tools 28.0.1 und höher enthalten: android_sdk/build-tools/version/
.
Allgemeine Verwendung
d8
erfordert nur einen Pfad zum kompilierten Java-Bytecode, den Sie in DEX-Bytecode umwandeln möchten. Beispiele:
d8 MyProject/app/build/intermediates/classes/debug/*/*.class
Der Eingabe-Bytecode kann in einer beliebigen Kombination aus *.class
-Dateien oder Containern sein, z. B. JAR-, APK- oder ZIP-Dateien. Sie können auch DEX-Dateien einschließen, damit d8
in die DEX-Ausgabe zusammengeführt wird. Dies ist nützlich, wenn Sie die Ausgabe aus einem inkrementellen Build einbeziehen.
Standardmäßig kompiliert d8
den Java-Bytecode in optimierte DEX-Dateien und enthält Informationen zur Fehlerbehebung, mit denen Sie während der Laufzeit Fehler im Code beheben können. Sie können jedoch optionale Flags einfügen, um einen inkrementellen Build auszuführen, Klassen angeben, die in der DEX-Hauptdatei kompiliert werden sollen, und Pfade zu zusätzlichen Ressourcen angeben, die zur Verwendung der Java 8-Sprachfunktionen erforderlich sind.
d8 path-to-input-files [options]
In der folgenden Tabelle werden die optionalen Flags beschrieben, die Sie mit d8
verwenden können:
Option | Beschreibung |
---|---|
--debug
|
Kompilieren Sie den DEX-Bytecode mit Informationen zur Fehlerbehebung, z. B. mit Symboltabellen für die Fehlerbehebung. Diese Option ist standardmäßig aktiviert. Damit dem DEX-Bytecode Informationen zur Fehlerbehebung hinzugefügt werden können, erwartet Verwenden Sie beim Kompilieren von DEX-Dateien für die Release-Version Ihrer Anwendung oder Bibliothek stattdessen das Flag |
--release
|
Kompilieren Sie DEX-Bytecode ohne Debug-Informationen. Übergeben Sie dieses Flag, wenn Sie Bytecode für eine öffentliche Version kompilieren. |
--output path
|
Geben Sie den gewünschten Pfad für die DEX-Ausgabe an. Standardmäßig gibt
Wenn Sie den Pfad und Namen einer ZIP- oder JAR-Datei angeben, erstellt |
--lib android_sdk/platforms/api-level/android.jar
|
Gib den Pfad zum android.jar deines Android SDK an.
Dieses Flag ist erforderlich, wenn Bytecode kompiliert wird, der Java 8-Sprachfeatures verwendet.
|
--classpath path
|
Geben Sie Klassenpfadressourcen an, die d8 möglicherweise zum Kompilieren der DEX-Dateien Ihres Projekts benötigt. Insbesondere müssen Sie bei d8 bestimmte Ressourcen angeben, wenn Sie Bytecode kompilieren, der Java 8-Sprachfeatures verwendet.
|
--min-api number
|
Geben Sie das minimale API-Level an, das die DEX-Ausgabedateien unterstützen sollen. |
--intermediate
|
Übergeben Sie dieses Flag, um d8 darüber zu informieren, dass Sie nicht den vollständigen Satz des Java-Bytecodes Ihres Projekts kompilieren. Dieses Flag ist nützlich, wenn inkrementelle Builds ausgeführt werden. Anstatt optimierte DEX-Dateien zu kompilieren, die auf einem Gerät ausgeführt werden sollen, erstellt d8 Zwischen-DEX-Dateien und speichert sie im angegebenen Ausgabe- oder Standardpfad.
Wenn Sie DEX-Dateien kompilieren möchten, die auf einem Gerät ausgeführt werden sollen, schließen Sie dieses Flag aus und geben Sie den Pfad zu den DEX-Zwischenklassen als Eingabe an. |
--file-per-class
|
Kompilieren Sie jede Klasse in separate DEX-Dateien. Wenn Sie dieses Flag aktivieren, können Sie mehr inkrementelle Builds ausführen. Dazu kompilieren Sie nur die geänderten Klassen neu. Wenn Sie inkrementelle Builds mit dem Android-Gradle-Plug-in ausführen, ist diese Optimierung standardmäßig aktiviert. Sie können dieses Flag nicht zusammen mit |
--no-desugaring
|
Java 8-Sprachfunktionen deaktivieren. Verwenden Sie dieses Flag nur, wenn Sie nicht vorhaben, Java-Bytecode zu kompilieren, der Java 8-Sprachfeatures verwendet. |
--main-dex-list path
|
Geben Sie eine Textdatei mit den Klassen an, die Da das Android-System beim Start der Anwendung zuerst die DEX-Hauptdatei lädt, können Sie dieses Flag verwenden, um bestimmte Klassen beim Start zu priorisieren, indem Sie sie in die DEX-Hauptdatei kompilieren. Dies ist besonders nützlich, wenn Legacy-Multidex-Bibliothek unterstützt werden, da zur Laufzeit nur Klassen in der DEX-Hauptdatei verfügbar sind, bis die Legacy-Multidex-Bibliothek geladen ist. Beachten Sie, dass jede DEX-Datei weiterhin das 64-K-Referenzlimit erfüllen muss. Geben Sie daher für die DEX-Hauptdatei nicht zu viele Klassen an, da sonst ein Kompilierungsfehler auftritt. Wenn Klassen mit Sie können dieses Flag nicht zusammen mit |
--pg-map file
|
Verwenden Sie file als Zuordnungsdatei für die Verteilung. |
--file-per-class-file
|
Erstellen Sie eine separate DEX-Datei pro .class-Eingabedatei. Synthetische Klassen mit ihrer ursprünglichen Klasse beibehalten. |
--desugared-lib file
|
Geben Sie die Konfiguration der gelöschten Bibliothek an. file ist die Konfigurationsdatei der gelöschten Bibliothek im JSON-Format. |
--main-dex-rules file
|
Proguard behält Regeln für Klassen in der primären DEX-Datei bei. |
--main-dex-list-output file
|
Ausgabe der resultierenden DEX-Hauptliste in |
|
javac -generierten Assertion-Code erzwingen.
|
|
Erzwingt die Deaktivierung von javac -generiertem Assertion-Code. Dies ist die Standardbehandlung des javac -Assertion-Codes beim Generieren von DEX-Dateien.
|
|
Ändern Sie den von javac generierten Assertion-Code nicht. Dies ist die Standardbehandlung von javac -Assertion-Codes beim Generieren von class -Dateien.
|
|
Ändern Sie den von javac und kotlinc generierten Assertion-Code, um die Methode handler method bei jedem Assertion-Fehler aufzurufen, anstatt sie auszulösen. handler method wird als Klassenname gefolgt von einem Punkt und dem Methodennamen angegeben. Die Handler-Methode muss ein einzelnes Argument vom Typ java.lang.Throwable und den Rückgabetyp void haben.
|
--thread-count number of threads
|
Geben Sie die Anzahl der Threads an, die für die Kompilierung verwendet werden sollen. Wenn keine Angabe erfolgt, basiert die Anzahl auf Heuristiken, wobei die Anzahl der Kerne berücksichtigt wird. |
--map-diagnostics[
:type] from-level to-level
|
Kartendiagnosen von type (Standardeinstellung) werden als from-level an to-level gemeldet, wobei from-level und to-level entweder „Info“, „Warnung“ oder „Fehler“ sind und der optionale type entweder der einfache oder voll qualifizierte Java-Typname einer Diagnose ist. Wenn type nicht angegeben ist, werden alle Diagnosen unter from-level zugeordnet. Schwerwiegende Compiler-Fehler können nicht zugeordnet werden. |
--version
|
Drucken Sie die Version von d8 aus, die Sie gerade verwenden.
|
--help
|
Hilfetext zur Verwendung von d8 drucken.
|
Inkrementelle Builds ausführen
Um die Build-Geschwindigkeit während der Entwicklung zu verbessern, z. B. bei Continuous-Integration-Builds, weisen Sie d8
an, nur einen Teil des Java-Bytecodes Ihres Projekts zu kompilieren. Wenn Sie beispielsweise die Dexierung pro Klasse aktivieren, können Sie nur die Klassen neu kompilieren, die Sie seit dem vorherigen Build geändert haben.
Mit dem folgenden Befehl wird ein inkrementeller Build einiger Klassen ausgeführt und das Dexing pro Klasse aktiviert. Der Befehl gibt auch ein Ausgabeverzeichnis für den inkrementellen Build an.
d8 MainActivity.class R.class --intermediate --file-per-class --output ~/build/intermediate/dex
Wenn d8
einen inkrementellen Build ausführt, werden zusätzliche Informationen in der DEX-Ausgabe gespeichert. d8
verwendet diese Informationen später, um die Option --main-dex-list
korrekt zu verarbeiten und DEX-Dateien während eines vollständigen Builds Ihrer Anwendung zusammenzuführen.
Bei der Verarbeitung von Lambda-Klassen in Java 8 erfasst d8
beispielsweise, welche Lambda-Klassen für jede Eingabeklasse erstellt werden. Wenn d8
während eines vollständigen Builds eine Klasse in der DEX-Hauptdatei enthält, prüft es die Metadaten, um sicherzustellen, dass alle für diese Klasse erstellten Lambda-Klassen auch in der DEX-Hauptdatei enthalten sind.
Wenn Sie bereits den gesamten Bytecode des Projekts über mehrere inkrementelle Builds in DEX-Dateien kompiliert haben, führen Sie einen vollständigen Build durch. Übergeben Sie dazu das Verzeichnis der DEX-Zwischendateien an d8
, wie im folgenden Befehl gezeigt.
Außerdem können Sie mit --main-dex-list
die Klassen angeben, die d8
in die DEX-Hauptdatei kompilieren soll. Da es sich bei der Eingabe um eine Reihe von Dateien handelt, die bereits in DEX-Bytecode kompiliert sind, sollte dieser Build schneller abgeschlossen werden als ein sauberer Build.
d8 ~/build/intermediate/dex --release --main-dex-list ~/build/classes.txt --output ~/build/release/dex
Bytecode kompilieren, der Java 8-Sprachfeatures verwendet
Mit d8
können Sie über einen Kompilierungsprozess, der desugaring genannt wird, die Java 8-Sprachfeatures in Ihrem Code verwenden. Beim Desugaring werden diese nützlichen Sprachfunktionen in Bytecode umgewandelt, der auf der Android-Plattform ausgeführt werden kann.
Android Studio und das Android-Gradle-Plug-in enthalten Klassenpfad-Ressourcen, die d8
benötigt, um das Desugaring für Sie zu aktivieren. Wenn Sie d8
über die Befehlszeile verwenden, müssen Sie sie jedoch selbst einfügen.
Eine solche Ressource ist die android.jar
aus deinem Android-Ziel-SDK. Diese Ressource enthält eine Reihe von Android-Plattform-APIs. Geben Sie den Pfad mit dem Flag --lib
an.
Eine weitere Ressource ist der in Ihr Projekt kompilierte Java-Bytecode, den Sie derzeit nicht in DEX-Bytecode kompilieren, sondern andere Klassen in DEX-Bytecode kompilieren müssen.
Wenn Ihr Code beispielsweise
Standard- und statische Schnittstellenmethoden verwendet, bei denen es sich um eine Java 8-Sprachfunktion handelt, müssen Sie mit diesem Flag den Pfad zum gesamten Java-Bytecode Ihres Projekts angeben, auch wenn Sie nicht den gesamten Bytecode in DEX-Bytecode kompilieren möchten. Das liegt daran, dass d8
diese Informationen benötigt, um den Code Ihres Projekts zu verstehen und Aufrufe an die Schnittstellenmethoden aufzulösen.
Im folgenden Codebeispiel wird ein inkrementeller Build einer Klasse ausgeführt, die auf eine Standardschnittstellenmethode zugreift:
d8 MainActivity.class --intermediate --file-per-class --output ~/build/intermediate/dex --lib android_sdk/platforms/api-level/android.jar --classpath ~/build/javac/debug