标签:
原文链接http://trickyandroid.com/the-dark-world-of-jack-and-jill/
去年Google发布了新的工具链 - Jack(Java Android 编译工具)和Jill(Jack中间库链接器),它们用于替换存在的javac+dx工具集。
本文我将试着整理关于这个工具链的我的想法和观点。
但在开始深挖Jack&Jill前,我打算绕个小圈,高度概括下已有的工具链并介绍你心爱的Android应用的编译过程。
坦白来说,我不会介绍完整的构建过程 - 我只关注于与我们主题最相关的部分 - 将Java源码转换成DEX文件。
从第一只恐龙踏足地球,编译过程就是这样了:
我们从Java源码开始。目的是 - 编译这些源码生成设备中JVM可理解的可执行指令。
对于Java(非Android)应用,我们只需要Java编译器(javac)。它可以编译Java源码并生成Java二进制码(*.class文件)。Java二进制码可通过常规的在你机器上运行的JVM执行。
问题是,在Android设备上,我们使用非标准的JVM。我们使用了修改版本,该版本高度又花了手机环境。例如JVM被称为Dalvik(或者ART在更加高效的L+设备上)。
因为修改了JVM,Java二进制码也需要修改,使得Dalvik可执行。这是dx工具的职责 - 它收到Java二进制码(.class文件),并转换成Android油耗的二进制文件(*.dx文件)。
值得一提是工程中包含第三方库时 - jar(或者aar)形式 -相反不需要处理,第三方库只是*.class文件的压缩集合。因此第三方库直接输入给dx工具,因为我们不需要编译它。
到现在相当的简单,对不?
随着时间推移,Android开发者变得更加富有经验,人们开始开发很酷的工具和插件,它们可以在Java二进制码级提升你的代码(a.k.a字节码操作)。
你看你听说过这些更流行的工具:
这给我们很酷的能力来后处理我们的代码w/o修改我们的原来的代码。F.i. Proguard可以分享你的Java字节码并删除无用部分(也称为最小化)。或者Retrolambda代替带匿名内部类的Java8的lambda表达式,这样你的’lambda表达式’就可以在不支持Java8特性的Android VM中工作了。
流程如下:
每个类(它的字节码)由字节码处理插件处理,并将结果传递给dx工具来生成最终的结果。
随着这样的工具开始井喷,显然Android Gradle构建系统不是真正为字节码处理器设计的 - 唯一能’抓住’Java字节码已准备好,而且又未被dx处理的时机的方法,就是添加Gradle任务依赖到Android Gradle插件创建的已存在的任务中。这样任务的名字是实现细节,它基于项目配置动态生成,并随着Android Gradle插件不断进化,Google持续更新它。这导致每次新Android插件发布,这种插件都不能正常工作了。
所以Google需要采取行动。他们做到了 - 他们引入了Transition API - 一个允许增加转换器的简单的API - 类将在构建过程的合适时机被调用。转换的输入是Java字节码。这允许插件开发者使用许多处理字节码的可靠方法,从而停止使用无文档的私有API。
同时,喜忧参半,Google的工程师超级忙于创造新事物,创造毁人心的东西!自动驾驶汽车!Jack和Jill!
Jack - 是编译器。类似javac,但是它做了些许不同的事:
如你所见,Jack直接将Java源码编译成Dex文件!我们不在有中间的*.class文件,因此dx工具不需要了!
但是等等!如果在工程中引入一个第三方库(.class文件集合),怎么办?
那么,Jill该出场了:
Jill可以处理class文件并转换成特殊的Jayce格式,该格式可用于Jack编译器的输入。
现在,让我们冷静思考一下… 对于我们沉迷的那些很酷的工具,将要发生什么?它们都需要.class文件,而Jack编译器不在需要.class文件了…
幸运的是,Jack提供了一些重要的开箱即用功能:
然后,缺点列表如下:
我意识到我刚提到的事情都是临时的,Google正在积极解决这些问题,但不幸的是,在人们开始意识到切换到新工具链的实际成本如此之高时,针对Android支持Java8特性的全部激动将完全褪去。
Jack是很酷的进步,它在编译链上将给Google带来更多的控制和灵活性,但是它处于初级阶段,它开始变得流行前,需要一段时间来积累。
你的,
Pavel Dudka
标签:
原文地址:http://blog.csdn.net/lihenair/article/details/51315403