Android预优化那些事
?https://blog.csdn.net/myfriend0/article/details/54970455
Android預優(yōu)化那些事
Preopt ART Dalvik
APK的預優(yōu)化原理和作用
?
- Android預優(yōu)化那些事
- 1什么是Android預優(yōu)化
- 2Android預優(yōu)化的原理
- 3Android ART優(yōu)化的過程
- 4Android預優(yōu)化的過程
- 5項目中執(zhí)行的效果
?
1.什么是Android預優(yōu)化
Android預優(yōu)化,也就是把Android在啟動或APP在運行時所需要做的一些事情,把這些事情轉(zhuǎn)移到編譯APK時完成,來達到更快的Android系統(tǒng)啟動速度和更快的APP運行速度。
2.Android預優(yōu)化的原理
先來回顧一下Android的發(fā)展史,在2014年的Google I/O大會上,Google隆重的發(fā)布了Android 4.4操作系統(tǒng),其中有一個環(huán)節(jié)著重介紹了ART(Android runtime),也就是虛擬機,也就是運行APP的環(huán)境,也就是運行Java代碼的虛擬機。雖然Android 4.4版本默認仍然用DVM(Dalvik VM),但到Android 5.0時ART就變成了默認模式,自此,DVM時代一去不再復返。
DVM和ART和Android的預優(yōu)化有什么關系?先了解Java的幾種虛擬機基本的工作機制:
- (1)JVM:JVM虛擬機運行的是java字節(jié)碼。Java文件到JVM的過程是:java -> java bytecode(class) -> java bytecode(jar)。
- (2)DVM:DVM虛擬機解析執(zhí)行的dex字節(jié)碼。Java文件到DVM的過程是:java -> java bytecode(class) -> dalvik bytecode(dex)。
- (3)ART:ART虛擬機執(zhí)行本地機器碼。Java文件到ART的過程是:java -> java bytecode(class) -> dalvik bytecode(dex) -> optimized android runtime machine code(oat)。
在Android 4.4(包括)之前用的是DVM,Android 4.4之后用的是ART,從java文件到虛擬機執(zhí)行代碼,ART比DVM多了oat的過程,ART所使用的AOT(Ahead-Of-Time)編譯,在應用首次安裝時,字節(jié)碼預編譯成機器碼存在本地,而DVM是典型的JIT(Just-In-Time),在此模式下,應用每次運行的時候,字節(jié)碼都需要即時編譯器轉(zhuǎn)換為機器碼再執(zhí)行,ART模式相對于DVM省去了解析字節(jié)碼的過程,占用內(nèi)存也相應減少,進而提高APP的運行效率,所以Andorid 5.0發(fā)布時,Google號稱Android系統(tǒng)可以跑在512 M的內(nèi)存的機器上,ART發(fā)揮了舉足輕重的作用。
3.Android ART優(yōu)化的過程
Zygote進程在啟動的過程中,創(chuàng)建ART虛擬機。在ART中,打包在APK里面的Dex字節(jié)碼是通過LLVM翻譯成本地機器指令的。LLVM是一個用來快速開發(fā)自己的編譯器的框架系統(tǒng),在Dalvik運行時中,APK在安裝的時候,安裝服務PackageManagerService會通過守護進程installd調(diào)用一個工具 dexopt對打包在APK里面包含有Dex字節(jié)碼的classes.dex進行優(yōu)化,優(yōu)化得到的文件保存在/data/dalvik-cache目錄 中,并且以.odex為后綴名,表示這是一個優(yōu)化過的Dex文件。在ART運行時中,APK在安裝的時候,同樣安裝服務 PackageManager?Service會通過守護進程installd調(diào)用另外一個工具dex2oat對打包在APK里面包含有Dex字節(jié)碼進翻譯。翻譯后得到的是一個ELF格式的oat文件,這個oat文件同樣是以.odex后綴結束,并且也是保存在/data/dalvik-cache目錄中。
4.Android預優(yōu)化的過程
在第三節(jié)可知,Android在首次啟動和首次安裝應用時,需要將字節(jié)碼翻譯成機器碼,這樣Android系統(tǒng)的啟動速度將會大大減慢,如果沒有預優(yōu)化,APP的運行速度也會加上翻譯所需要的時間。所以,這個翻譯的工作需要轉(zhuǎn)移到編譯上面來,也就是所,在編譯APK文件時,將會預先對APK進行翻譯的優(yōu)化,然后再打包到系統(tǒng)里面去,這樣Android系統(tǒng)在首次啟動時,就不再需要花費大量的時間去翻譯APK的字節(jié)碼。下文贅述這個過程的控制過程:
在項目的device.mk文件中有如下的配置:
如上圖,當編譯user版本時,WITH_DEXPREOPT將會置成true,
繼續(xù)看WITH_DEXPREOPT的作用范圍,如下:
在上圖中,過濾各種條件,會執(zhí)行LOCAL_DEX_PREOPT := $(DEX_PREOPT_DEFAULT)語句,而DEX_PREOPT_DEFAULT的定義在:
拋開其它條件,在user環(huán)境下編譯,LOCAL_DEX_PREOPT會被置換成true,LOCAL_DEX_PREOPT是怎樣控制編譯呢?
在編譯APP時,LOCAL_DEX_PREOPT是true,將會按照相應的規(guī)則優(yōu)化APK文件,這個規(guī)則定在dex_preopt.mk文件中。
5.項目中執(zhí)行的效果
在pixi5-5 4G的項目中Dialer、MMS、Contacts采用獨立的倉庫,服務器出版本的時候,不再編譯源碼中的這三個模塊,而是已app list的方式,定制apk文件,所以就需要本地編譯好apk文件,在上傳到服務器。先來看看eng環(huán)境下(或關閉預優(yōu)化)和user環(huán)境下編譯App后會有什么不一樣。
在eng環(huán)境下(或關閉預優(yōu)化),以TctDialer為例,編譯后輸出的目錄是這樣的:
在看看user下編譯的情況,編譯后輸出的目錄是這樣的:
對比可發(fā)現(xiàn),沒有預優(yōu)化的apk文件有個classes.dex文件,而預優(yōu)化的沒有這個文件了,java代碼跑哪里去了,可以看到輸出目錄多了oat子目錄,編譯后的java正好在這個目錄下。
因此,在user環(huán)境下編譯,生成的apk文件是不能直接上傳到服務器的,因為這個apk已經(jīng)沒有java的代碼了。所以在編譯apk時,把mk文件中添加LOCAL_DEX_PREOPT := false把預編譯關閉。
如果在user下編譯的apk,push到daily的系統(tǒng)中,apk依然能夠運行,不是沒有classes.dex文件了嗎?java代碼都沒有了,為什么還能運行?在第三節(jié)可知道,在android系統(tǒng)啟動是會優(yōu)化系統(tǒng)的app,所以daily中的APK的java代碼被緩存到手機本地了,push user下編譯的apk運行時依然運行的是daily版中apk緩存下來的code。
總結
以上是生活随笔為你收集整理的Android预优化那些事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android系统底层驱动多个物理按键上
- 下一篇: Android Usb的研究