使用Jack编译
點擊打開鏈接
本篇文章翻譯自 Compiling with Jack
Jack工具鏈
Jack是一個Android工具鏈,用于將Java源碼編譯成Android dex字節(jié)碼。它替換了之前的Android工具鏈,即由javac, ProGrard, jarjar和dx多個工具組成的集合。
Jack工具鏈帶來了以下優(yōu)勢:
完全開源
AOSP中可以找到;歡迎合作伙伴貢獻。加快編譯速度
Jack對降低編譯時間有具體的支持:pre-dexing,增量編譯和Jack編譯服務(wù)器。處理壓縮,混淆,重新打包和多dex
不再需要使用像ProGuard之類單獨的包。
圖1. Java概覽
.jack庫格式
Jack擁有它自己的文件格式.jack,它包含了針對庫的預(yù)編譯dex代碼,可以允許快速編譯(pre-dex)。
圖2. Jack庫文件內(nèi)容
Jill
Jill工具可以將現(xiàn)有的.jar庫文件轉(zhuǎn)換成庫格式,如下圖所示。
圖3. 導(dǎo)入現(xiàn)有的.jar庫的工作流
編譯Android時使用Jack
為了使用Jack,你無需做任何不同的事情 - 只管使用標準的makefile命令來編譯你的整體項目。Jack是M版本默認的Android編譯工具鏈。
第一次使用Jack時,它會在你的電腦上啟動一個本地Jack編譯服務(wù)器:
- 這個服務(wù)器帶來了內(nèi)在的加速,因為它避免了在每一次編譯時啟動一個新的JRE JVM主機,加載Jack代碼,初始化Jack和準備JIT。同時在小型的編譯中它也提供了很好的編譯時間(例如,增量模式)。
- 這個服務(wù)器也是控制并行Jack編譯數(shù)量的一個短期解決方案,因此可以避免你的電腦過載(內(nèi)存和磁盤問題),因為它限制了并行編譯的數(shù)量。
在沒有編譯一段空閑時間之后,Jack服務(wù)器會關(guān)閉自己。它在本地接口使用了兩個TCP端口,因此對外并不可用。通過編輯$HOME/.jack文件可以修改所有的這些參數(shù)(并行編譯的數(shù)量,超時時間,端口號,等等)。
$HOME/.jack文件
$HOME/.jack文件包含了Jack服務(wù)器的變量設(shè)置,這些設(shè)置以bash的語法的形式。
這里是可用的設(shè)置與它們的定義與默認值:
- SERVER=true 啟用Jack服務(wù)器特性。
- SERVER_PORT_SERVICE=8072 設(shè)置編譯目的的TCP端口。
- SERVER_PORT_ADMIN=8073 設(shè)置管理母的的TCP端口。
- SERVER_COUNT=1 目前不使用。
- SERVER_NB_COMPILE=4 允許最大的并行編譯數(shù)量。
- SERVER_TIMEOUT=60 無編譯時服務(wù)器關(guān)閉自身前等待的時間(單位為秒)
- SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} 服務(wù)器日志寫入的文件。默認情況下,該變量可以被環(huán)境變量覆蓋。
- JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} 主機上啟動JVM的默認命令。默認情況下,該變量可以被環(huán)境變量覆蓋。
[非翻譯]目前的默認設(shè)置已經(jīng)不是上面的值,所以這里的默認值僅供參考。
而且$HOME/.jack文件也找不到,只能找到$HOME/.jack-settings文件。
Jack故障處理
如果編譯時電腦無響應(yīng)或以“Out of memory error”的錯誤編譯失敗
你可以通過編輯$HOME/.jack文件將SERVER_NB_COMPILE改為一個較低的值來降低Jack同時進行的編譯數(shù)量來改進這個狀況。
[非翻譯]這個解決方案在實際當(dāng)中并不能解決問題,具體解決方案參考我前邊的文章 Android源代碼編譯筆記(支持5.x及以上版本)。
如果以“Cannot launch background server”的錯誤編譯失敗
最可能的原因是TCP端口已經(jīng)被使用。嘗試編輯$HOME/.jack文件(SERVER_PORT_SERVICE和SERVER_PORT_ADMIN變量)來修復(fù)。
如果問題沒有解決,情上報并且附上你的編譯日志和Jack服務(wù)器日志(查看下方’查找Jack日志’了解從哪里找到服務(wù)器日志文件)。為了移除這個狀況,編輯$HOME/.jack文件將SERVER改為false來禁用Jack編譯服務(wù)器。不幸的是,這將會顯著降低編譯速度并且強制你啟動make -j(make的選項-l)。
如果編譯被卡住沒有任何進展
請上報給我們并且提供以下附加信息(盡可能):
- 卡住所在的命令行
- 命令行的輸出
- 執(zhí)行jack-admin server-stat的結(jié)果
- $HOME/.jack文件
- 服務(wù)器狀態(tài)為dumped時的服務(wù)器日志內(nèi)容。為了獲取這些
- 通過運行jack-admin list-server找出Jack后臺服務(wù)器
- 發(fā)送kill -3命令到該服務(wù)器,將它的狀態(tài)導(dǎo)出到日志文件
- 查看下面的找出Jack日志,來定位服務(wù)器日志文件
- 執(zhí)行l(wèi)s -lR $TMPDIR/jack-$USER命令的結(jié)果
- 運行ps j -U $USER命令的結(jié)果
你可以通過殺掉Jack后臺服務(wù)器(使用jack-admin kill-server)來解除目前的情況,然后刪除你的臨時目錄(/tmp或者$TMPDIR)下的jack-$USER內(nèi)的臨時文件夾。
如果遇到其它錯誤
要上報bugs或者請求特性,請使用我們的公共問題跟蹤器,在 http://b.android.com 上可用。使用Jack tool bug report或者Jack tool feature request模板。請將Jack的日志附到bug上報。
查找Jack日志
- 如果你使用dist target運行make命令,Jack的日志文件在$ANDROID_BUILD_TOP/out/dist/logs/jack-server.log
- 否則你可以通過運行jack-admin server-log命令來查找
如果是可再生Jack失敗,你可以通過設(shè)置一個變量得到更為詳細的日志,如下所示:
$ export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"- 1
- 2
- 1
- 2
然后使用標準的makefile命令來編譯整個項目或者你的項目并且附上它的標準輸出和錯誤。
移除詳細的編譯日志可以使用:
$ unset ANDROID_JACK_EXTRA_ARGS- 1
- 1
Jack的局限性
使用Jack的特性
Jack支持Java 1.7并且繼承了如下所述的額外特性。
Predexing
當(dāng)生成Jack庫文件時,作為pre-dex,庫文件的.dex被生成和存儲在.jack庫文件的內(nèi)部。當(dāng)編譯時,Jack從每個庫中復(fù)用這些pre-dex。
所有的庫都進行了pre-dexed。
圖4. 帶有pre-dex的Jack庫
局限性
目前,如果在編譯時使用了壓縮/混淆/重新打包,那么Jack不能復(fù)用pre-dex的庫。
增量編譯
增量編譯指的是從上次編譯后,只有觸摸過的部分和它們的依賴會被重新編譯。當(dāng)修改只發(fā)生在一小部分時,增量編譯要比全部編譯快很多。
局限性
當(dāng)遺留的壓縮,混淆,重新打包或者多dex啟用時,增量編譯會關(guān)閉。
啟用增量編譯
目前,增量編譯沒有默認開啟。在你想要增量編譯的項目的Android.mk文件中加入下面的代碼:
- 1
- 1
注意:使用Jack第一次編譯你的項目時,如果某些依賴沒有構(gòu)建,使用mma命令構(gòu)建它們,然后你就可以使用標準的構(gòu)建命令。
壓縮和混淆
Jack支持壓縮和混淆并且可以使用混淆配置文件來開啟壓縮和混淆特性。這里是支持和忽略的選項:
支持的通用選項
通用選項包括以下:
- @
- -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不優(yōu)化
- -dontpreverify // Jack不預(yù)先驗證
- -skipnonpubliclibraryclasses
- -dontskipnonpubliclibraryclasses
- -dontskipnonpubliclibraryclassmembers
- -keepdirectories
- -target
- -forceprocessing
- -printusage
- -whyareyoukeeping
- -optimizations
- -optimizationpasses
- -assumeonsideeffects
- -allowaccessmodification
- -mergeinterfacesaggressively
- -overloadaggressively
- -microedition
- -verbose
- -dontnote
- -dontwarn
- -ignorewarnings
- -printconfiguration
- -dump
其它選項將會產(chǎn)生錯誤。
重新打包
Jack使用jarjar的配置文件來進行重新打包。
Jack與”rule”規(guī)則類型兼容,但是不兼容”zap”或”keep”規(guī)則類型。如果你需要”zap”或”keep”規(guī)則類型,請發(fā)送一份特性請求并且附上在你的app里要如何使用這些特性的描述。
多dex支持
由于dex文件對于方法的上限是65K,所以超過65K方法的app必須要分成多個dex文件(有關(guān)多dex的更多信息參考 Building Apps with Over 65K Methods)。
Jack提供原生與遺留的多dex的支持。
總結(jié)
- 上一篇: 关于Android Service真正的
- 下一篇: Adb shell命令打电话测试4G