根据此公告,Jack 工具链已被弃用。不过,在我们提供替代工具之前,您可以继续使用它启用 Java 8 语言功能。
Jack 是一种新型 Android 工具链,用于将 Java 源代码编译成 Android dex 字节码。它取代了之前由 javac、ProGuard、jarjar 和 dx 等多种工具组成的 Android 工具链。
Jack 工具链具有以下优势:
请注意,从 Android 7.0 (N) 开始,Jack 支持使用 JaCoCo 衡量代码覆盖率。如需了解详情,请参阅使用 JaCoCo 衡量代码覆盖率和 Java 8 语言功能。
图 1. Jack 概览
Jack 具有自己的 .jack 文件格式,其中包含相应库的预编译 dex 代码,可实现更快速的编译 (dex 预处理)。
图 2. Jack 库文件内容
Jill 工具可将现有的 .jar 库转换为新的库格式,如下图所示。
图 3. 导入现有 .jar 库的工作流程
要使用 Jack,您只需使用标准的 Makefile 命令来编译树或您的项目即可,无需进行任何其他操作。Jack 是适合 M 的默认 Android 编译工具链。
首次使用 Jack 时,它会在您的计算机上启动一个本地 Jack 编译服务器:
如果没有任何编译工作,在空闲一段时间之后,Jack 服务器会自行关闭。它使用了 localhost 接口上的两个 TCP 端口,因此无法从外部访问。您可以通过修改 $HOME/.jack
文件来修改所有这些参数(并行编译的数量、超时、端口号等)。
$HOME/.jack
文件包含 Jack 服务器变量的设置,采用纯 bash 语法编写。
以下是可用设置及其定义和默认值:
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 编译因“Out of memory error”(内存不足错误)而失败
您可以通过修改 $HOME/.jack
并将 SERVER_NB_COMPILE
改为较低的值来减少同时进行的 Jack 编译的数量,以针对所遇到的问题予以改善。
如果您的编译因“Cannot launch background server”(无法启动后台服务器)而失败
最可能的原因是您的计算机上的 TCP 端口都被占用了。请尝试通过修改 $HOME/.jack
(SERVER_PORT_SERVICE
和 SERVER_PORT_ADMIN
变量)进行更改。
如果问题没有解决,请报告此问题并附上您的编译日志和 Jack 服务器日志(请参阅下文中的“查找 Jack 日志”,了解从何处找到服务器日志文件)。要解决这种情况,请通过修改 $HOME/.jack
并将 SERVER
更改为 false 来停用 jack 编译服务器。遗憾的是,这将大大减慢您的编译速度,并可能强制您使用加载控制(make
的选项“-l
”)启动 make -j
。
如果您的编译卡住了,没有任何进展
请报告此问题,并向我们提供以下附加信息(如果可能的话):
jack-admin server-stat
的结果。
$HOME/.jack
文件。
jack-admin list-server
查找 Jack 后台服务器进程。
kill -3
命令,将其状态转储到日志文件中。
ls -lR $TMPDIR/jack-$USER.
的结果。
ps j -U $USER.
的结果。
您应该能够通过停止 Jack 后台服务器(使用 jack-admin kill-server
),然后移除临时目录(/tmp
或 $TMPDIR
)的 jack-$USER
中包含的临时目录来解决卡住的情况。
如果您有任何其他问题
要报告错误或请求功能,请使用我们的公开问题跟踪工具(位于 http://b.android.com 上),以及 Jack 工具错误报告或 Jack 工具功能请求模板。请在错误报告中附上 Jack 日志。
查找 Jack 日志
|
对于可重现的 Jack 错误,您可以通过设置一个变量来获取更详细的日志,如下所示:
$ export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
然后使用标准 Makefile 命令编译树或您的项目,并附上其标准输出和错误。
要移除详细的编译日志,请使用以下命令:
$ unset ANDROID_JACK_EXTRA_ARGS
Jack 支持 Java 编程语言 1.7,并集成了下面列出的额外功能。
在生成 Jack 库文件时,系统也会生成该库的 .dex 文件并将其作为 dex 预处理文件存储在 .jack 库文件中。在进行编译时,Jack 会重复使用每个库的 dex 预处理文件。
所有库均经过 dex 预处理。
图 4. 包含 dex 预处理文件的 Jack 库
目前,如果在编译过程中使用了压缩/混淆/重新打包功能,则 Jack 不会重复使用库的 dex 预处理文件。
增量编译指的是,仅重新编译自上次编译后出现过更改的组件及其依赖项。当只有少数组件出现过更改时,进行增量编译可能比完整编译快得多。
当压缩、混淆、重新打包或对旧版 multi-dex 启用后,增量编译会被停用。 Benny: 如何理解 multi-dex legacy
目前,增量编译默认处于未启用状态。要启用增量编译,请将以下行内容添加到您要进行增量编译的项目的 Android.mk 文件中:
LOCAL_JACK_ENABLED := incremental
注意:首次使用 Jack 编译项目时,如果某些依赖项未编译,请使用 mma
进行编译,之后您可以使用标准编译命令。
Jack 支持压缩和混淆,并使用 proguard 配置文件来实现压缩和混淆功能。以下是支持的选项和忽略的选项:
常用选项包括:
@
-include
-basedirectory
-injars
-outjars // only 1 output jar supported
-libraryjars
-keep
-keepclassmembers
-keepclasseswithmembers
-keepnames
-keepclassmembernames
-keepclasseswithmembernames
-printseeds
压缩选项包括:
-dontshrink
混淆选项包括:
-dontobfuscate
-printmapping
-applymapping
-obfuscationdictionary
-classobfuscationdictionary
-packageobfuscationdictionary
-useuniqueclassmembernames
-dontusemixedcaseclassnames
-keeppackagenames
-flattenpackagehierarchy
-repackageclasses
-keepattributes
-adaptclassstrings
忽略的选项包括:
-dontoptimize // Jack does not optimize
-dontpreverify // Jack does not preverify
-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”规则类型不兼容。如果您需要使用“zap”或“keep”规则类型,请提交一项功能请求,并在其中说明您在应用中如何使用该功能。
由于 dex 文件的方法数上限为 65K,因此方法数超过 65K 的应用必须拆分成多个 dex 文件(要详细了解多 dex,请参阅构建方法数超过 65K 的应用)。
Jack 支持本地多 dex 和旧版多 dex。