在沒有jack以前,google一直使用的sun/oracle的java編譯器javac用作android的官方編譯器檐嚣。
javac是jdk中的java編譯器幕随,將java文件編譯成class文件,那么我們來看一下之前的Android的java文件是怎么一步一步變成可以在dalvik虛擬機(jī)中運(yùn)行的dex文件的。
簡介
2016 年 3 月 10 日囚戚, Google 向外界發(fā)布了 Android N 的預(yù)覽版,并宣布了 Android N 的Roadmap轧简,Android N 的最終版源代碼將于今年 8 或 9 月份釋出到 AOSP 項(xiàng)目驰坊。
在眾多的 Android N 新特性中,有一項(xiàng)新工具鏈的出現(xiàn)與 Android 生態(tài)圈的所有開發(fā)者息息相關(guān)哮独,即 Jack & Jill 編譯器的引入拳芙。
在依賴了 Sun/Oracle 的 Java 編譯器十年之后,Android 終于有了自己的 Java 編譯器皮璧。
本文試圖對(duì)市面上非常有限的資料進(jìn)行總結(jié)舟扎,向大家介紹 Jack & Jill 的緣起,工作方式和原理悴务。
Jack 是 Java Android Compiler Kit 的縮寫睹限,它可以將 Java 代碼直接編譯為 Dalvik 字節(jié)碼,并負(fù)責(zé) Minification, Obfuscation, Repackaging, Multidexing, Incremental compilation讯檐。它試圖取代 javac/dx/proguard/jarjar/multidex 庫等工具羡疗。
Jill 是 Jack Intermediate Library Linker 的縮寫别洪,它負(fù)責(zé) “Shielding JACK from Java byte code”叨恨;實(shí)際上輔助 Jack 對(duì).class 做預(yù)處理,生成
.jack
文件
- git 源代碼地址是https://android.googlesource.com/toolchain/jill挖垛。
Source
雖然 Google 是在宣布 Android N 預(yù)覽版時(shí)隆重介紹了Jack & Jill痒钝。但是,早在 2014 年 Google 就對(duì)外宣布了新編譯器 Jack 的存在[meet our new experimental toolchain](http://android-developers.blogspot.jp/2014/12/hello-world-meet-our-new-experimental.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+blogspot/hsDu+(Android+Developers+Blog), 它的開發(fā)啟動(dòng)時(shí)間更是遠(yuǎn)遠(yuǎn)早于 2014 年痢毒。
- 一家名叫 FlexyCore 的小公司基于 GCC toolchain 開發(fā)了 Android 平臺(tái)上的 AOT 編譯器送矩,被 Google 看中并于 2013 年被收購
- FlexyCore team 基于 LLVM toolchain 開發(fā)了 ART,并成為 Android 5.0 之后的缺省 Java Runtime
- FlexyCore team 基于 Eclipse ecj 編譯器開始開發(fā) Jack哪替,基于 ASM4 開發(fā) Jill益愈。 他們?cè)缭?2014 年 2 月就開始提交 Jill 的代碼了Jill initial commit; 3 月份開始提交 Jack的代碼Jack initial commit
- 自 Android build-tools 21.1 開始,里面已經(jīng)內(nèi)置 jack.jar 和 jill.jar
- Android Gradle plugin 自 0.14 開始支持 Jack & Jillinitial commit
- 自 Android 6.0 開始蒸其,Jack & Jill 成為 AOSP 的官方編譯器, 也就是說所有的 Android 6.0 ROM 都是 Jack 編譯出來的link,也代表 Google 認(rèn)為 Jack 達(dá)到了一定的成熟度
- 預(yù)計(jì)等 Android 7.0 正式發(fā)布時(shí)库快,Jack 可能會(huì)成為官方推薦的編譯器
原因
可能是
- 提高編譯速度
- 應(yīng)對(duì) Oracle 的法律訴訟
- 將編譯器掌控權(quán)拿在自己手中摸袁,不再受制于 Oracle,可以做一些 Android only 的優(yōu)化
javac的編譯流程
簡單的說义屏,將 Java 代碼和依賴庫編譯為 dex 有兩個(gè)大的階段
javac (.java –> .class) –> dx (.class –> .dex)
javac 將 java 代碼編譯為 java bytecode, 以.class的形式存在; 以 jar 和 aar 形式存在的依賴庫靠汁,代碼在里面以一堆.class 的形式存在
Proguard 工具讀取 Proguard 配置,對(duì).class做 shrinking, obfuscation闽铐,輸出 Proguard mapping
dx 將多個(gè).class轉(zhuǎn)化為單一的 classes.dex ; 如果 dex 方法數(shù)超過 65k, 就生成 classes.dex, classes1.dex…classesN.dex
jack編譯流程
新的編譯過程只有一個(gè)階段了蝶怔,它完全拋棄了 javac, ProGuard, jarjar 等工具,一個(gè)工具搞定一切
Jack (.java –> .jack –> .dex)
各種依賴庫仍然以 jar/aar 的形式存在
輔助工具 Jill 將根據(jù)依賴庫中的.class生成 Jayce 格式的 IL兄墅,并調(diào)用 Jack 做 pre-dex 并生成.jack踢星,此過程只在編譯 app 時(shí)發(fā)生一次
Jack 將 java 源代碼也編譯為.jack,然后將多個(gè).jack轉(zhuǎn)化為單一的.dex; 如果 dex 方法數(shù)超過 65k, 就生成 classes.dex, classes1.dex…classesN.dex
pre-dex 的詳細(xì)解釋可以參閱此鏈接new-build-system