Jack 是 Android 6.0 - 8.1 的預設 Android 建置工具鏈
Jack 是一個 Android 工具鏈,可將 Java 原始碼編譯為 Android dex 字節碼。您不必做任何不同的事情來使用 Jack - 只需使用標準 makefile 命令來編譯樹或您的專案。 Android 8.1 是最後一個使用 Jack 的版本。
關於傑克
Jack的工作原理如圖1所示。
圖 1.插孔概覽。
傑克庫格式
Jack 有自己的.jack
檔案格式,其中包含函式庫的預編譯 dex 程式碼,允許更快的編譯(pre-dex)。
圖 2.Jack庫文件內容。
吉爾
如下圖所示,Jill工具將現有的.jar
庫轉換為新的庫格式。
圖 3.導入現有.jar
庫的工作流程。
Jack編譯伺服器
第一次使用 Jack 時,它會在您的電腦上啟動本機 Jack 編譯伺服器。該伺服器:
- 帶來內在的加速,因為它避免了在每次編譯時啟動新的主機 JRE JVM、載入 Jack 程式碼、初始化 Jack 以及預熱 JIT。它還在小型編譯期間(例如,在增量模式下)提供非常好的編譯時間。
- 是控制並行Jack編譯數量的短期解決方案。伺服器避免了電腦過載(記憶體或磁碟問題),因為它限制了並行編譯的數量。
Jack 伺服器在空閒時間後自行關閉,沒有進行任何編譯。它使用本機主機介面上的兩個 TCP 端口,並且在外部不可用。所有參數(並行編譯數、逾時、連接埠號碼等)都可以透過編輯$HOME/.jack
檔案來修改。
$HOME/.jack 文件
$HOME/.jack
檔案包含完整 bash 語法中 Jack 伺服器變數的以下設定:
-
SERVER=true
啟用 Jack 的伺服器功能。 -
SERVER_PORT_SERVICE=8072
設定伺服器的 TCP 連接埠號碼以供編譯之用。 -
SERVER_PORT_ADMIN=8073
設定用於管理目的的伺服器的 TCP 連接埠號碼。 -
SERVER_COUNT=1
未使用。 -
SERVER_NB_COMPILE=4
設定允許的平行編譯的最大數量。SERVER_TIMEOUT=60
設定伺服器在關閉自身之前必須等待的空閒秒數(無需進行任何編譯)。SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}
設定寫入伺服器日誌的檔案。預設情況下,該變數可以由環境變數重載。 -
JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}
設定用於在主機上啟動 JVM 的預設指令。預設情況下,該變數可以被環境變數重載。
Jack 編譯疑難排解
問題 | 行動 |
---|---|
您的電腦在編譯期間變得無回應,或者您遇到 Jack 編譯因記憶體不足錯誤而失敗的情況 | 透過編輯$HOME/.jack 並將SERVER_NB_COMPILE 更改為較低的值,減少同時進行的 Jack 編譯的數量。 |
編譯失敗,無法啟動後台伺服器 | 最可能的原因是 TCP 連接埠已在您的電腦上使用。透過編輯$HOME/.jack ( SERVER_PORT_SERVICE 和SERVER_PORT_ADMIN 變數)來變更連接埠。若要解除這種情況,請透過編輯$HOME/.jack 並將SERVER 改為false 來停用 Jack 編譯伺服器。不幸的是,這會顯著減慢您的編譯速度,並可能迫使您啟動帶有負載控制的make -j ( make 的選項-l )。 |
編譯卡住了沒有任何進展 | 要解除這種情況,請使用jack-admin kill-server 終止 Jack 後台伺服器,然後刪除臨時目錄的jack-$USER 中包含的臨時目錄( /tmp 或$TMPDIR )。 |
找到傑克日誌
如果您使用 dist 目標執行make
指令,則 Jack 日誌位於$ANDROID_BUILD_TOP/out/dist/logs/jack-server.log
。否則,您可以透過執行jack-admin server-log
來尋找日誌。如果出現可重複的 Jack 故障,您可以透過設定以下變數來取得更詳細的日誌:
export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
使用標準 makefile 命令編譯樹(或您的專案)並附加標準輸出和錯誤。若要刪除詳細的建置日誌,請執行:
unset ANDROID_JACK_EXTRA_ARGS
插孔限制
預設情況下,Jack 伺服器只能由一台電腦上的一個使用者使用。若要支援其他用戶,請為每個用戶選擇不同的連接埠號碼並相應地調整SERVER_NB_COMPILE
。您也可以透過在$HOME/.jack
中設定SERVER=false
停用 Jack 伺服器。由於目前的vm-tests-tf
集成,CTS 編譯速度很慢。不支援字節碼操作工具(例如 JaCoCo)。
使用傑克
Jack 支援 Java 程式語言 1.7 並整合了下述附加功能。
預索引
產生 Jack 庫檔案時,會產生該庫的.dex
,並將其作為 pre-dex 儲存在.jack
庫檔案內。編譯時,Jack 重用了每個函式庫中的 pre-dex。所有庫均已預先索引。
圖 4.具有預 dex 的 Jack 庫。
如果在編譯中使用縮略、混淆或重新打包,Jack 不會重複使用函式庫 pre-dex。
增量編譯
增量編譯意味著僅重新編譯自上次編譯以來觸及的元件(及其相依性)。當變更僅限於一組元件時,增量編譯可能比完整編譯快得多。
增量編譯預設為停用狀態(並且在啟用收縮、混淆、重新打包或多 dex 遺留功能時會自動停用)。若要啟用增量構建,請將以下行新增至要增量建置的專案的Android.mk
檔案:
LOCAL_JACK_ENABLED := incremental
縮小和混淆
Jack 使用 ProGuard 設定檔來啟用收縮和混淆。
常見選項包括以下內容:
-
@
-
-include
-
-basedirectory
-
-injars
-
-outjars
(僅支援 1 個輸出 jar) -
-libraryjars
-
-keep
-
-keepclassmembers
-
-keepclasseswithmembers
-
-keepnames
-
-keepclassmembernames
-
-keepclasseswithmembernames
-
-printseeds
收縮選項包括以下:
-
-dontshrink
混淆選項包括以下內容:
-
-dontobfuscate
-
-printmapping
-
-applymapping
-
-obfuscationdictionary
-
-classobfuscationdictionary
-
-packageobfuscationdictionary
-
-useuniqueclassmembernames
-
-dontusemixedcaseclassnames
-
-keeppackagenames
-
-flattenpackagehierarchy
-
-repackageclasses
-
-keepattributes
-
-adaptclassstrings
忽略的選項包括以下內容:
-
-dontoptimize
(Jack 不優化) -
-dontpreverify
(Jack 不進行預先驗證) -
-skipnonpubliclibraryclasses
-
-dontskipnonpubliclibraryclasses
-
-dontskipnonpubliclibraryclassmembers
-
-keepdirectories
-
-target
-
-forceprocessing
-
-printusage
-
-whyareyoukeeping
-
-optimizations
-
-optimizationpasses
-
-assumenosideeffects
-
-allowaccessmodification
-
-mergeinterfacesaggressively
-
-overloadaggressively
-
-microedition
-
-verbose
-
-dontnote
-
-dontwarn
-
-ignorewarnings
-
-printconfiguration
-
-dump
重新包裝
Jack使用jarjar設定檔進行重新打包。雖然 Jack 與“rule”規則類型相容,但它與“zap”或“keep”規則類型不相容。
多重分包支持
Jack 提供內建和傳統的多重分包支援。由於 dex 檔案限制為 65K 方法,因此具有超過 65K 方法的應用程式必須拆分為多個 dex 檔案。有關更多詳細信息,請參閱為具有超過 64K 方法的應用程式啟用 multidex
,Jack 是 Android 6.0 - 8.1 的預設 Android 建置工具鏈
Jack 是一個 Android 工具鏈,可將 Java 原始碼編譯為 Android dex 字節碼。您不必做任何不同的事情來使用 Jack - 只需使用標準 makefile 命令來編譯樹或您的專案。 Android 8.1 是使用 Jack 的最後一個版本。
關於傑克
Jack的工作原理如圖1所示。
圖 1.插孔概覽。
Jack庫格式
Jack 有自己的.jack
檔案格式,其中包含函式庫的預編譯 dex 程式碼,允許更快的編譯(pre-dex)。
圖 2.Jack庫文件內容。
吉爾
如下圖所示,Jill工具將現有的.jar
庫轉換為新的庫格式。
圖 3.導入現有.jar
庫的工作流程。
Jack編譯伺服器
第一次使用 Jack 時,它會在您的電腦上啟動本機 Jack 編譯伺服器。該伺服器:
- 帶來內在的加速,因為它避免了在每次編譯時啟動新的主機 JRE JVM、載入 Jack 程式碼、初始化 Jack 以及預熱 JIT。它還在小型編譯期間(例如,在增量模式下)提供非常好的編譯時間。
- 是控制並行Jack編譯數量的短期解決方案。伺服器避免了電腦過載(記憶體或磁碟問題),因為它限制了並行編譯的數量。
Jack 伺服器在空閒時間後自行關閉,沒有進行任何編譯。它使用本機主機介面上的兩個 TCP 端口,並且在外部不可用。所有參數(並行編譯數、逾時、連接埠號碼等)都可以透過編輯$HOME/.jack
檔案來修改。
$HOME/.jack 文件
$HOME/.jack
檔案包含完整 bash 語法中 Jack 伺服器變數的以下設定:
-
SERVER=true
啟用 Jack 的伺服器功能。 -
SERVER_PORT_SERVICE=8072
設定伺服器的 TCP 連接埠號碼以供編譯之用。 -
SERVER_PORT_ADMIN=8073
設定用於管理目的的伺服器的 TCP 連接埠號碼。 -
SERVER_COUNT=1
未使用。 -
SERVER_NB_COMPILE=4
設定允許的平行編譯的最大數量。SERVER_TIMEOUT=60
設定伺服器在關閉之前必須等待的空閒秒數(無需進行任何編譯)。SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}
設定寫入伺服器日誌的檔案。預設情況下,該變數可以由環境變數重載。 -
JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}
設定用於在主機上啟動 JVM 的預設指令。預設情況下,該變數可以被環境變數重載。
Jack 編譯疑難排解
問題 | 行動 |
---|---|
您的電腦在編譯期間變得無回應,或者您遇到 Jack 編譯因記憶體不足錯誤而失敗的情況 | 透過編輯$HOME/.jack 並將SERVER_NB_COMPILE 更改為較低的值,減少同時進行的 Jack 編譯的數量。 |
編譯失敗,無法啟動後台伺服器 | 最可能的原因是 TCP 連接埠已在您的電腦上使用。透過編輯$HOME/.jack ( SERVER_PORT_SERVICE 和SERVER_PORT_ADMIN 變數)來變更連接埠。若要解除這種情況,請透過編輯$HOME/.jack 並將SERVER 改為false 來停用 Jack 編譯伺服器。不幸的是,這會顯著減慢您的編譯速度,並可能迫使您啟動帶有負載控制的make -j ( make 的選項-l )。 |
編譯卡住了沒有任何進展 | 要解除這種情況,請使用jack-admin kill-server 終止 Jack 後台伺服器,然後刪除臨時目錄的jack-$USER 中包含的臨時目錄( /tmp 或$TMPDIR )。 |
找到傑克日誌
如果您使用 dist 目標執行make
指令,則 Jack 日誌位於$ANDROID_BUILD_TOP/out/dist/logs/jack-server.log
。否則,您可以透過執行jack-admin server-log
來尋找日誌。如果出現可重複的 Jack 故障,您可以透過設定以下變數來取得更詳細的日誌:
export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
使用標準 makefile 命令編譯樹(或您的專案)並附加標準輸出和錯誤。若要刪除詳細的建置日誌,請執行:
unset ANDROID_JACK_EXTRA_ARGS
插孔限制
預設情況下,Jack 伺服器只能由一台電腦上的一個使用者使用。若要支援其他用戶,請為每個用戶選擇不同的連接埠號碼並相應地調整SERVER_NB_COMPILE
。您也可以透過在$HOME/.jack
中設定SERVER=false
停用 Jack 伺服器。由於目前的vm-tests-tf
集成,CTS 編譯速度很慢。不支援字節碼操作工具(例如 JaCoCo)。
使用傑克
Jack 支援 Java 程式語言 1.7 並整合了下述附加功能。
預索引
產生 Jack 庫檔案時,會產生該庫的.dex
,並將其作為 pre-dex 儲存在.jack
庫檔案內。編譯時,Jack 重用了每個函式庫中的 pre-dex。所有庫均已預先索引。
圖 4.具有預 dex 的 Jack 庫。
如果在編譯中使用縮略、混淆或重新打包,Jack 不會重複使用函式庫 pre-dex。
增量編譯
增量編譯意味著僅重新編譯自上次編譯以來觸及的元件(及其相依性)。當變更僅限於一組元件時,增量編譯可能比完整編譯快得多。
增量編譯預設為停用狀態(並且在啟用收縮、混淆、重新打包或多 dex 遺留功能時會自動停用)。若要啟用增量構建,請將以下行新增至要增量建置的專案的Android.mk
檔案:
LOCAL_JACK_ENABLED := incremental
縮小和混淆
Jack 使用 ProGuard 設定檔來啟用收縮和混淆。
常見選項包括以下內容:
-
@
-
-include
-
-basedirectory
-
-injars
-
-outjars
(僅支援 1 個輸出 jar) -
-libraryjars
-
-keep
-
-keepclassmembers
-
-keepclasseswithmembers
-
-keepnames
-
-keepclassmembernames
-
-keepclasseswithmembernames
-
-printseeds
收縮選項包括以下:
-
-dontshrink
混淆選項包括以下內容:
-
-dontobfuscate
-
-printmapping
-
-applymapping
-
-obfuscationdictionary
-
-classobfuscationdictionary
-
-packageobfuscationdictionary
-
-useuniqueclassmembernames
-
-dontusemixedcaseclassnames
-
-keeppackagenames
-
-flattenpackagehierarchy
-
-repackageclasses
-
-keepattributes
-
-adaptclassstrings
忽略的選項包括以下內容:
-
-dontoptimize
(Jack 不優化) -
-dontpreverify
(Jack 不進行預先驗證) -
-skipnonpubliclibraryclasses
-
-dontskipnonpubliclibraryclasses
-
-dontskipnonpubliclibraryclassmembers
-
-keepdirectories
-
-target
-
-forceprocessing
-
-printusage
-
-whyareyoukeeping
-
-optimizations
-
-optimizationpasses
-
-assumenosideeffects
-
-allowaccessmodification
-
-mergeinterfacesaggressively
-
-overloadaggressively
-
-microedition
-
-verbose
-
-dontnote
-
-dontwarn
-
-ignorewarnings
-
-printconfiguration
-
-dump
重新包裝
Jack使用jarjar設定檔進行重新打包。雖然 Jack 與“rule”規則類型相容,但它與“zap”或“keep”規則類型不相容。
多重分包支持
Jack 提供內建和傳統的多重分包支援。由於 dex 檔案限制為 65K 方法,因此具有超過 65K 方法的應用程式必須拆分為多個 dex 檔案。有關更多詳細信息,請參閱為具有超過 64K 方法的應用程式啟用 multidex