如果日常做Android開發的你不關注Google針對編譯優化的話做的努力的話,會對D8和R8這兩個名詞會比較陌生,最近要升級工程的Gradle版本,正好涉及到開啟D8和R8的問題,筆者就簡單整理解釋下這兩者的作用和概念,
一張圖概括Android編譯器進化

圖引自:https://proandroiddev.com/android-cpu-compilers-d8-r8-a3aa2bfbc109
從Java開始,JVM通過在硬體上面添加一層抽象來適配不同的CPU架構來實作跨平臺,通過javac編譯器將Java代碼編譯成位元組碼,進而運行在虛擬機當中,這樣就無需關注底層作業系統、記憶體和CPU的差異,應用開發者只需要關注業務邏輯,
回到Android,我們的代碼是需要跑在容量更小,電量更小的移動設備當中,JVM那套就不太適用了,所以Google就針對Android開發了Dex編譯器來編譯dex格式的位元組碼,而運行Dex位元組碼的Android虛擬機被稱為Dalvik,因為Dalvik存在不少局限性,Google后來又退出ART虛擬機,ART使用了AOT(Ahead of Time)編譯器,跟Davik的區別是,它不是在運行時決議和JIT編譯,而是直接運行提前編譯好的.oat檔案,所以它的運行速度會更快, 按道理說到了AOT,Android的編譯速度已經有了不錯的效果,但是Java Android != Java SE,Java7開始引入的新語言特性不能直接用在Android開發中,為了能夠用上Java8新特性,Google增加了一步編譯程序—脫糖(desugaring),但這一步會導致更長的編譯時間,這也是為什么Google會推出D8和R8編譯器來優化編譯速度,
什么是脫糖?
脫糖 即在編譯階段將在語法層面一些底層位元組碼不支持的特性轉換為基礎的位元組碼結構,(比如 List 上的泛型脫糖后在位元組碼層面實際為 Object); Android 工具鏈對 Java8 語法特性脫糖的程序可謂豐富多彩,當然他們的最終目的是一致的:使新的語法可以在所有的設備上運行,
D8
D8的功能是將Java位元組碼轉化成dex代碼,D8作為DX的一個替代方案,編譯流程如下圖所示:

Android Studio 3.1版本開始,將D8作為默認的Dex編譯器,如果想關閉D8,可以在gradle.properties里添加如下配置:
android.enableD8=false
android.enableD8.desugaring=false
開啟D8的好處
- 編譯更快、時間更短
- DEX編譯時占用內容更小
- .dex檔案更小
- D8編譯的.dex檔案擁有相同或者更好的運行性能
如果你的工程已經使用Java 8盡可能開啟D8編譯,不然可能會出現編譯錯誤,
R8
R8是用來替代Proguard的一個工具,是新一代的代碼壓縮工具, R8之前采用D8+Proguard的形式構建,R8則將混淆和D8工具進行整合,目的是加速構建時間和減少輸出apk的大小,

Gradle插件版本達到3.4.0及以上,默認會開始R8進行代碼優化,如果你不想開啟R8,可以在gradle.properties里添加如下配置:
android.enableR8=false
開啟R8的好處
- 代碼縮減:規避64參考限制
- 資源縮減:移除不使用的資源
- 混淆代碼:減小DEX檔案大小
- 優化代碼:進一步減小DEX檔案大小
參考:https://developer.android.google.cn/studio/build/shrink-code
R8 VS Proguard
Time

Size


評測結果圖引自:https://github.com/madsager/santa-tracker-android
參考資料
- https://juejin.cn/post/6844903773144350734
- https://juejin.cn/post/6914497144346902542#heading-1
- https://juejin.cn/post/6844903951846899719#heading-10
- https://blog.csdn.net/jamin0107/article/details/81123154
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278406.html
標籤:AI
