d8

d8 是 Android Studio 和 Android Gradle 外掛程式的指令列工具 用於將專案的 Java 位元碼編譯成 DEX 位元碼 在 Android 裝置上d8 可讓您在 新增到應用程式的程式碼中

d8 也包含在 Android Build Tools 28.0.1 以上版本的獨立工具中:android_sdk/build-tools/version/

一般使用情況

d8 只需要連往已編譯 Java 位元碼的路徑 轉換為 DEX 位元碼的位元組例如:

d8 MyProject/app/build/intermediates/classes/debug/*/*.class

輸入的位元碼可以是 *.class 檔案或容器的任意組合,例如 JAR、APK 或 ZIP 檔案。您也可以加入 d8 的 DEX 檔案,將這些檔案合併到 DEX 輸出中,這很實用 尤其是從漸進式建構作業的輸出內容

根據預設,d8 會將 Java 位元碼編譯成最佳化的 DEX 檔案,其中包含可在執行階段期間對程式碼進行偵錯的偵錯資訊。不過,您可以選擇 指定執行漸進式建構作業的類別 應編譯為主要 DEX 檔案,並指定 使用 Java 8 語言功能所需的額外資源。

d8 path-to-input-files [options]

下表說明瞭您可以與 d8 搭配使用的選用旗標:

選項 說明
--debug

編譯 DEX 位元碼以納入偵錯資訊,例如偵錯符號 表格。

這個選項預設為啟用。如要在 DEX 位元碼中包含偵錯資訊,d8 輸入的 Java 位元碼需要包含這項資訊。例如,如果您使用 javac 編譯程式碼,就必須傳遞 -g 旗標,將偵錯資訊納入輸出 Java 位元碼。

為應用程式的發布版本編譯 DEX 檔案時, 請改用 --release 旗標。

--release

編譯不含偵錯資訊的 DEX 位元碼。不過 d8 包含產生模型時使用的部分資訊 堆疊追蹤和記錄例外狀況

在針對公開版本編譯位元碼時傳送這個旗標。

--output path

指定 DEX 的輸出路徑。根據預設 d8 會在目前工作中輸出 DEX 檔案 目錄。

如果您指定 ZIP 或 JAR 檔案的路徑和名稱,d8 會建立指定檔案,並包含輸出 DEX 檔案。如果指定現有目錄的路徑,d8 會輸出該目錄中的 DEX 檔案。

--lib android_sdk/platforms/api-level/android.jar 指定 Android SDK 的 android.jar 路徑。 編譯使用 Java 8 語言功能的位元碼時必須使用這個旗標。
--classpath path 指定 d8 可能需要編譯的類別路徑資源 匯入您專案的 DEX 檔案具體來說,d8 要求你 指定特定資源在編譯位元碼的 Java 8 語言功能
--min-api number 指定輸出 DEX 檔案支援的最低 API 級別。
--intermediate 傳遞這個旗標,讓 d8 知道您並未編譯完整的專案 Java 位元碼。這個標記很實用: 執行漸進式建構作業而不是編譯最佳化的 DEX 檔案 您預期在裝置上執行的版本,d8 會建立中繼資訊 DEX 檔案,然後儲存在指定的輸出或預設路徑中。

如要編譯您想在裝置上執行的 DEX 檔案,請排除這項旗標,並指定中繼 DEX 類別的路徑做為輸入。

--file-per-class

將每個類別編譯成不同的 DEX 檔案。

啟用此旗標後,您就能透過 系統只會針對已變更的類別重新編譯。表演時 使用 Android Gradle 外掛程式執行漸進式建構作業時 預設啟用的功能

您無法在指定時使用這個旗標 --main-dex-list

--no-desugaring 停用 Java 8 語言功能。除非您不打算編譯使用 Java 8 語言功能的 Java 位元碼,才需要使用這個標記。
--main-dex-list path

指定文字檔案,當中列出 d8 應包含的類別 位於主要 DEX 檔案中,檔案名稱通常為 classes.dex。 當您未使用此旗標指定類別清單時, d8 無法保證哪些類別會包含在主要類別 DEX 檔案。

由於 Android 系統會在您啟動應用程式時優先載入主要 DEX 檔案,因此您可以在啟動應用程式時使用這個旗標,將特定類別編譯成主要 DEX 檔案,優先排定這些類別。以備不時之需 尤其是在支援舊版 Multidex 時,因為只有主要 DEX 中的類別 檔案可以在執行階段使用,直到舊版 Multidex 程式庫為止 就會引發這個事件。

請注意,每個 DEX 檔案都必須符合 64K 參考資料上限。因此請避免 為主要 DEX 檔案指定過多類別,或取得 編譯錯誤。根據預設,使用 Cloud Build 指定類別時 --main-dex-listd8 只包含這些項目 主要 DEX 檔案中的類別。以免發生課程相關問題 更容易偵錯。如果指定 --release 模式,d8 會嘗試減少數字 開發人員提供給應用程式的發布版本 在主要 DEX 檔案中盡可能加入最多其他類別,直到 已達 64K 上限

您無法在指定時使用這個旗標 --file-per-class

--pg-map file 使用 file 做為發布的對應檔案。
--file-per-class-file

為每個輸入 .class 檔案產生獨立的 DEX 檔案。

在合成類別中保有原始類別。

--desugared-lib file

指定脫糖程序的程式庫設定。

file 是 JSON 格式的脫糖程式庫設定檔 格式。

--main-dex-rules file Proguard 保有活動規則的 主要 DEX 檔案。
--main-dex-list-output file file 中輸出產生的主要 DEX 清單。

--force-enable-assertions [:class_or_package_name...]

--force-ea [:class_or_package_name...]

強制啟用 javac 產生的斷言程式碼。

--force-disable-assertions [:class_or_package_name...]

--force-da [:class_or_package_name...]

強制停用 javac 產生的斷言程式碼。這個 是 javac 斷言程式碼的預設處理作業 產生 DEX 檔案。

--force-passthrough-assertions [:class_or_package_name...]

--force-pa [:class_or_package_name...]

請勿變更 javac 產生的斷言程式碼。這個 是 javac 斷言程式碼的預設處理作業 正在產生 class 個檔案

--force-assertions-handler:handler method [:class_or_package_name...]

--force-ah:handler method [:class_or_package_name...]

變更 javackotlinc 產生的斷言 程式碼,透過每次斷言叫用 handler method 方法 而不是擲回錯誤已指定 handler method ,後面加上一個點和方法的名稱。 處理常式方法必須使用一個型別的單一引數 java.lang.Throwable 且傳回類型為 void
--thread-count number of threads 指定要用於編譯的執行緒數量。如未指定 數字採用經驗法則, 都屬於此類
--map-diagnostics[ :type] from-level to-level 回報為「type」(預設) 的地圖診斷 from-levelto-level,地點:from-levelto-level 為「資訊」、「警告」或「錯誤」之一和 選用 type 可以是簡易或完整格式 診斷的 Java 類型名稱。如果未指定 typefrom-level 中的所有診斷資料皆已對應。 請注意,無法對應編譯器的嚴重錯誤。
--version 列印目前使用的 d8 版本。
--help 列印使用 d8 的說明文字。

執行漸進式建構

加快開發期間的建構速度 (例如用於持續整合) 建構,指示 d8 只編譯專案中 Java 的部分 位元碼。例如,如果您啟用每個類別的 dex,即可僅重新編譯自上次建構之後已修改的類別。

下列指令會執行幾個類別的漸進式建構,並啟用每個類別的內容排除功能。這個指令也會指定漸進式建構作業的輸出目錄。

d8 MainActivity.class R.class --intermediate --file-per-class --output ~/build/intermediate/dex

d8 執行漸進式建構作業時,會在 DEX 輸出。d8 稍後會使用這些資訊正確處理 使用 --main-dex-list 選項,並在應用程式的完整建構期間合併 DEX 檔案。

舉例來說,處理 Java 8 lambda 類別時,d8 會追蹤 系統會為每個輸入類別建立 lambda 類別。在完整版中,當d8 主要 DEX 檔案中包含類別,該類別會查詢中繼資料,確保所有 為該類別建立的 lambda 類別也會納入 DEX 檔案。

如果您將專案的所有位元碼編譯成 DEX 檔案, 跨多個漸進式建構作業,傳遞完整建構作業 將中繼 DEX 檔案目錄寫入 d8,如下列指令所示。 此外,您還可以指定要讓 d8 編譯到主應用程式的類別 使用 --main-dex-list 的 DEX 檔案。因為輸入內容是一組檔案 ,即使這個版本已編譯為 DEX 位元碼 而非乾淨的建構作業

d8 ~/build/intermediate/dex --release --main-dex-list ~/build/classes.txt --output ~/build/release/dex

編譯使用 Java 8 語言功能的位元碼

d8 可讓您使用 Java 8 語言功能 透過名為 Deugaring 的編譯程序執行。脫糖轉換 將這些實用的語言功能轉換為位元碼 可在 Android 裝置上執行 平台。

Android Studio 和 Android Gradle 外掛程式包含類別路徑 d8 需要為您啟用脫糖程序所需的資源。不過,透過指令列使用 d8 時,您必須自行加入。

這類資源是目標 Android SDK 的 android.jar。這個 資源包含一組 Android 平台的 API指定路徑 --lib 旗標。

另一項資源是編譯至專案中的 Java 位元碼組合 目前未編譯為 DEX 位元碼,但需要編譯其他 轉換為 DEX 位元碼

舉例來說,如果程式碼使用 預設和靜態介面方法 - 都是 Java 8 種語言功能,您必須使用這個標記來指定所有 的 Java 位元碼 (即使您不打算編譯所有位元碼) 轉換為 DEX 位元碼這是因為 d8 需要這些資訊瞭解專案程式碼,並解析介面方法的呼叫。

下列程式碼範例會針對可存取預設介面方法的類別,執行漸進式建構作業:

d8 MainActivity.class --intermediate --file-per-class --output ~/build/intermediate/dex
--lib android_sdk/platforms/api-level/android.jar
--classpath ~/build/javac/debug