Google 又弃坑了,Jack+Jill vs. javac+dx

Google 又弃坑了,Jack+Jill vs. javac+dx

kenken
Google于今年3.14宣布抛弃两个迷之人物:Jack (Java Android Compiler Kit) and Jill (Jack Intermediate Library Linker)

Jack + Jill被搞出来是原本是取代 javac + dx的,也就去年的事情,当大家纷纷准备在build.gradle里面纠结要不要打开 `useJack` 的时候,Google说,未来为支持Java8新特性,不再考虑Jack/Jill。


原文链接:Future of Java 8 Language Feature Support on Android

于是我还专门去Stackoverflow相关帖子里面捣了个乱:How to enable Jack (Java Android Compiler Kit) in android studio

Google从来没有官方讲过Jack and Jill为什么叫这个,于是我蛋疼地Google了一下;Google告诉我的是在Montreal有一家商店叫Jack & Jill,虽然我在那里待了五年,但是从来没去过。这个觉得比较靠谱:"All shall be well, and Jack shall have Jill"(中文可以翻译成"有情人终成眷属")这句话里的Jack 和 Jill是谁?他们之间有什么故事?,没有文化的我又涨知识了。

这不是一篇搞笑文,是一篇技术文,搞笑至此。最后放一张Jack/Jill的照片和大家挥挥手。


如果你还不知道Jack/Jill

这个是(你应该熟悉的)原来的Android APP 编译部分:

源代码文件 .java 通过标准JDK的 javac编译器 (Oracle/Sun JDK or OpenJDK) 编译成 .class文件(包含的是stack-based bytecode),长成这样,有汇编基础的不用多做解释。

然后诸多 class文件,与项目依赖的jar文件(jar简单来说就是其他项目编译好的class文件的zip)进行“链接”,交给 dx 这个命令(位于 <android-sdk>/build-tools/x.x.x/dx),这个程序负责把所有的stack-based bytecode 变为Dalvik bytecode。Dalvik bytecode是一种 register-based bytecode,长这样:(同样不解释)

这就是由来已久的javac+dx toolchain。基于这套toolchain的代码工具有很多,比如proguard混淆器;proguard会处理javac产生的class文件进行混淆和缩减,然后再交给dx。

2014年2月6号,第一个Jack/Jill的commit来了,Google准备改变这个流程,Jack/Jill带来的新流程如下:

简单来说 jack = .java to .dex + jill = .class to .dex,来替代 javac = .java to .class + dx = .class to dex。这个改动的原因猜测如下:

1. 为了支持 Java8的一些特性,lambda。这些需要新的dex bytecode支持(例如invoke-dynamic,谢谢评论提醒,见:lambda support for Android

2. Jack是一个编译器(替代javac),这样Google未来可以在Jack上增加更加针对Android的优化

相比Jack,Jill更是辅助作用就是把legacy的class转换成dex;另外,proguard的支持被添加到了Jack里。

为什么弃坑了呢?

Google post原话:

Over time, we realized the cost of switching to Jack was too high for our community when we considered the annotation processors, bytecode analyzers and rewriters impacted.
个人表示三枪全中,我们团队主攻annotation processors, bytecode analyzers and rewriters。事实上,团队内部的Github上至今还有一个issue叫:Support Jack/Jill and its Java8 features。现在可以放心地准备review and close了。

具体一点:

1. jack + jill 比 javac+dx慢(很多)耗内存,意味着更长的build过程,而且没有Instant Run,编译器是个长年累月的活

2. annotation processors: 用来处理Java Annotation的,比如依赖注入类的Dagger。同时ButterKnife以及一麻袋star上千的库的作者Jake Wharton说Android N Preview已经(开始)支持annotation processors,只不过来的太晚。Annotation-based的库可以大大减少代码量,如果编译器不支持的话库作者都没有办法改过来,只能等

3. bytecode analyzers:这类就广了,最常见的就是Lint类工具,用来静态找bug的(比如这个变量定义了没有用之类的)。其他的bytecode analyzers还有原来Java用来分析内存泄露、多线程竞争的工具。不支持的原因很简单,Java bytecode没有了,要么analyzers都按照Dalvik bytecode重写一遍。同样这个不支持是致命的

4. rewriters:重写以及插桩工具,有不少工具是基于objectweb.ASM处理标准Java bytecode的(幸好我们团队的是DEX的),这些工具广泛用于PGO (profiling-guided optimization) 还有其他动态分析。

总结

Android Dalvik的起点是拥有“over 1 billion设备”的Java,这点眼光是对的(虽然当年的Dalvik VM是多么烂):1)快速吸引大量Java程序员;2)基本原来Java的工具可以用到Android;3)巧妙解决了License问题(Dalvik VM is not JVM,避免了Trademark的问题)


除了给Dalvik VM不断改进(JIT,GC等),后来搞出了ART,想法也是不错的(保留了Dalvik bytecode,javac+dx继承了所有Java的工具,GC硬伤得以改善)

但是Jack/Jill从产品上的确是一个值得质疑的决定,要知道产品永远要比技术本身更重要。


扩展阅读

Android - The dark side of Jack and Jill (写得不错)

Jack And Jill Are Google's New Compilers For Android App Developers (2014年的当初)

Android N Java 8 features (Jack compiler) and Kotlin interop (还有一个捣乱的叫Kotlin)

lambda support for Android(Lambda的bytecode支持还有Retrolambda)

图片搜集自因特网

「真诚赞赏,手留余香」
还没有人赞赏,快来当第一个赞赏的人吧!
10 条评论