欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解dex優(yōu)化對(duì)Arouter查找路徑的影響

 更新時(shí)間:2021年06月18日 10:43:28   作者:vivo互聯(lián)網(wǎng)技術(shù)  
dex簡(jiǎn)單說(shuō)就是優(yōu)化后的android版.exe。每個(gè)apk安裝包里都有。相對(duì)于PC上的java虛擬機(jī)能運(yùn)行.class,android上的Davlik虛擬機(jī)能運(yùn)行.dex。本文將著重介紹dex優(yōu)化對(duì)Arouter查找路徑的影響

一、前言

疑問(wèn):dex文件是什么?dex文件優(yōu)化又是什么?

dex文件優(yōu)化會(huì)給項(xiàng)目帶來(lái)什么問(wèn)題,怎么解決這些問(wèn)題?

1.1 APK的編譯和打包流程

1、通過(guò)aapt打包資源文件res,對(duì)應(yīng)生成R.java、resources.arsc和res文件(二進(jìn)制&非二進(jìn)制保持原來(lái)的代碼)

2、處理aidl文件,生成java接口文件(沒(méi)有aidl則忽略)

3、通過(guò)java compile編譯R.java、java接口文件,生成對(duì)應(yīng).class文件(java compiler)

4、運(yùn)用dex命令,將.class文件和第三方sdk庫(kù)中的.class文件轉(zhuǎn)換成classes.dex文件

5、通過(guò)apkbuilder將aapt生成的CompiledResources和其他資源文件以及classes.dex文件打包生成apk

6、同樣的,可以使用Jarsigner工具,對(duì)上面的apk進(jìn)行debug或者release簽名

apk的編譯和打包流程圖如下:

實(shí)際項(xiàng)目開(kāi)發(fā)中,5、6兩個(gè)步驟,可以借助jenkins平臺(tái)直接生成release包即可滿足需求。

1.2 dex文件的應(yīng)用場(chǎng)景

再來(lái)看看dex文件常用的場(chǎng)景,比較流行的有:APK 的瘦身、熱修復(fù)、插件化、應(yīng)用加固、Android 逆向工程、64 K 方法數(shù)限制。

拿方法數(shù)限制舉例,在上面的第4步,將class文件轉(zhuǎn)換成dex文件,默認(rèn)只會(huì)生成一個(gè)dex文件,單個(gè)dex文件中的方法數(shù)不能超過(guò)65536,不然編譯會(huì)報(bào)錯(cuò),但是我們?cè)陂_(kāi)發(fā)App時(shí)肯定會(huì)集成一堆庫(kù),方法數(shù)一般都是超過(guò)65536的,解決這個(gè)問(wèn)題的辦法就是:一個(gè)dex裝不下,用多個(gè)dex來(lái)裝,gradle增加一行配置:multiDexEnabled true。

dex文件的應(yīng)用場(chǎng)景網(wǎng)上介紹的很多,本文不做介紹。而是對(duì)項(xiàng)目中實(shí)際遇到的問(wèn)題進(jìn)行剖析,從而對(duì)dex優(yōu)化有進(jìn)一步的理解。

二、dex到vdex、odex

2.1 ART預(yù)優(yōu)化

ART(Android runtime)是什么,它是虛擬機(jī),運(yùn)營(yíng)java代碼、APP用的。參考Android發(fā)展史,Android 5.0把ART作為默認(rèn)的虛擬機(jī),而不是Android4.4及之前使用的DVM(Dalvik VM)了。

回顧一下DVM和ART和Android的關(guān)系,我們先來(lái)了解運(yùn)行Java的幾種虛擬機(jī)的工作機(jī)制:(1)JVM:JVM虛擬機(jī)運(yùn)行的是java字節(jié)碼。Java文件到JVM的過(guò)程是:java -> java bytecode(class) -> java bytecode(jar)

DVM:DVM虛擬機(jī)解析執(zhí)行的dex字節(jié)碼。Java文件到DVM的過(guò)程是:java -> java bytecode(class) -> dalvik bytecode(dex)

ART:ART虛擬機(jī)執(zhí)行本地機(jī)器碼。Java文件到ART的過(guò)程是:java -> java bytecode(class) -> dalvik bytecode(dex) -> optimized android runtime machine code(oat)

可以看到,DVM到ART的演變,實(shí)際上是java文件到虛擬機(jī)的執(zhí)行代碼的過(guò)渡,相對(duì)而言,ART多了oat的過(guò)程,ART使用AOT(Ahead-Of-Time)編譯,在應(yīng)用第一次安裝的時(shí)候,字節(jié)碼預(yù)編譯成機(jī)器碼存在本地,DVM是使用JIT(Just-In-Time)編譯,在應(yīng)用每次運(yùn)行的時(shí)候,字節(jié)碼都需要通過(guò)編譯器即時(shí)轉(zhuǎn)換為機(jī)器碼才能繼續(xù)執(zhí)行。ART相對(duì)于DVM,省去了每次解析字節(jié)碼的過(guò)程,所以運(yùn)行時(shí)占用的內(nèi)存會(huì)減少,提升應(yīng)用的運(yùn)行效率。

2.2 ART的運(yùn)行方式

ART在Android5.0時(shí)代,號(hào)稱使用AOT即可讓系統(tǒng)運(yùn)行在512M的機(jī)器上。從 Android 7.0(簡(jiǎn)稱 N)開(kāi)始,ART結(jié)合 AOT、即時(shí)(JIT)編譯和配置文件引導(dǎo)型編譯。

這幾種模式可以組合配置,以谷歌的Pixel 設(shè)備舉例,配置了以下編譯流程:

1)最初安裝應(yīng)用時(shí)不進(jìn)行任何 AOT 編譯。應(yīng)用前幾次運(yùn)行時(shí),系統(tǒng)會(huì)對(duì)其進(jìn)行解譯,并對(duì)經(jīng)常執(zhí)行的方法進(jìn)行 JIT 編譯。

2)當(dāng)設(shè)備閑置和充電時(shí),編譯守護(hù)進(jìn)程會(huì)運(yùn)行,以便根據(jù)在應(yīng)用前幾次運(yùn)行期間生成的配置文件對(duì)常用代碼進(jìn)行 AOT 編譯。

下一次重新啟動(dòng)應(yīng)用時(shí)將會(huì)使用配置文件引導(dǎo)型代碼,并避免在運(yùn)行時(shí)對(duì)已經(jīng)編譯過(guò)的方法進(jìn)行 JIT 編譯。在應(yīng)用后續(xù)運(yùn)行期間進(jìn)行了 JIT 編譯的方法將會(huì)被添加到配置文件中,然后編譯守護(hù)進(jìn)程將會(huì)對(duì)這些方法進(jìn)行 AOT 編譯。

ART 包括一個(gè)編譯器(dex2oat 工具)和一個(gè)為啟動(dòng) Zygote 而加載的運(yùn)行時(shí)(libart.so)。dex2oat 工具接受一個(gè) APK 文件,并生成一個(gè)或多個(gè)編譯文件,然后運(yùn)行時(shí)將會(huì)加載這些文件。文件的個(gè)數(shù)、擴(kuò)展名和名稱會(huì)因版本而異,但在 Android O 版本中,將會(huì)生成以下文件:

vdex:其中包含 APK 的未壓縮 DEX 代碼,另外還有一些旨在加快驗(yàn)證速度的元數(shù)據(jù)。

odex:其中包含 APK 中經(jīng)過(guò) AOT 編譯的方法代碼。

art (optional):其中包含 APK 中列出的某些字符串和類的 ART 內(nèi)部表示,用于加快應(yīng)用啟動(dòng)速度。

2.3 vdex、odex的作用

解壓一個(gè)APK(以廠商的系統(tǒng)應(yīng)用包舉例)的包,可以看到下面的結(jié)構(gòu),不含有任何dex文件

再看下這個(gè)應(yīng)用在手機(jī)中的目錄結(jié)構(gòu),vdex、odex文件包含apk的所有代碼,正常也會(huì)包含classes.dex文件。由于vdex、odex是機(jī)器碼,沒(méi)辦法直接轉(zhuǎn)成可以查看的二級(jí)制碼查看(也可能是我使用的工具不對(duì))。

2.4 vdex、odex與classes.dex關(guān)系

可能是系統(tǒng)編譯的bug,也可能是生成了ART文件之后,對(duì)odex、vdex文件做了二次處理,現(xiàn)象是這樣的,嘗試獲取odex中的dex文件,提示不含有dex文件。

為了再次確認(rèn)odex里面是否真的含有dex文件,使用010Editor再次確認(rèn),可以看到recent Files下面仍然是沒(méi)有dex文件的。

嘗試獲取vdex中的dex文件,也是無(wú)法獲取的。

所以說(shuō),odex(或者vdex)中含有classes.dex的說(shuō)法是不正確的。

三、Arouter是什么

阿里的一個(gè)路由組件,功能很多,我這邊的實(shí)際使用場(chǎng)景是進(jìn)行頁(yè)面跳轉(zhuǎn)。具體功能可以參考阿里峰會(huì)上對(duì)arouter的介紹。

借鑒峰會(huì)中提到的一點(diǎn)作為鋪墊,也是我們下面將要講述的一點(diǎn)?!白詈笙敕窒淼木褪茿Router的未來(lái)開(kāi)發(fā)計(jì)劃。未來(lái)ARouter會(huì)支持插件化并且支持生成映射關(guān)系文檔,因?yàn)椴寮乾F(xiàn)在很多大型APP中會(huì)使用的技術(shù)方案,很多的Dex和功能是動(dòng)態(tài)地下發(fā)到APP中的,而在這種情況下,是無(wú)法找到所有的Dex文件的,也就是對(duì)于沒(méi)有加載過(guò)的Dex而言,里面的映射關(guān)系是跳轉(zhuǎn)不過(guò)去的,所以一旦Dex文件位置發(fā)生變動(dòng),常規(guī)的方案是無(wú)法找到Dex的,也不能實(shí)現(xiàn)映射文件初始化,這一部分會(huì)在后面的版本中進(jìn)行支持”。

阿里可以識(shí)別的arouter路徑如下:

換句話說(shuō),arouter可能因?yàn)閐ex文件的位置變化或者路徑變化,而無(wú)法找到。

四、踩坑

4.1 現(xiàn)象

2.4中提到了odex文件中不含有dex,而arouter查找路徑遵循分組按需加載的規(guī)則,歸結(jié)到底,實(shí)際上就是對(duì)class文件的查找,如下圖:

而class文件的信息記錄在dex文件中,所以出現(xiàn)了異常,使用arouter進(jìn)行頁(yè)面跳轉(zhuǎn)的時(shí)候,出現(xiàn)classNotFound exception。

4.2 解決方案

想要找到解決方案,就要知道怎么樣讓odex對(duì)arouter路徑不產(chǎn)生影響,這方面,可能在沒(méi)有相關(guān)經(jīng)驗(yàn)的時(shí)候,很難找到解決方案,只能一點(diǎn)點(diǎn)查找。通過(guò)搜索ART的工作原理,找到文章《配置ART》,其中文章提到:

也就是說(shuō)通過(guò)配置LOCAL_DEX_PREOPT的屬性,可以防止odex優(yōu)化,于是找到Android.mk中設(shè)置該屬性的地方進(jìn)行設(shè)置LOCAL_DEX_PREOPT := nostripping。

既在編譯的時(shí)候做dex優(yōu)化(生成odex文件),又不從apk里剝離dex。于是有了下面的apk生成之后的路徑對(duì)比,再看下dex不被剝離的路徑,下面含有了classes.dex文件。

使用jadx打開(kāi)這個(gè)classes.dex文件,發(fā)現(xiàn)arouter的路徑文件就在這里,所以arouter的跳轉(zhuǎn)正常了,異常不再出現(xiàn)。

五、總結(jié)

odex優(yōu)化這種系統(tǒng)做的事情,往往會(huì)出現(xiàn)一些意想不到的結(jié)果,如果你負(fù)責(zé)廠商的應(yīng)用,經(jīng)常需要內(nèi)置項(xiàng)目,這時(shí)候要注意了,當(dāng)你的應(yīng)用中含有第三方框架的時(shí)候,要注意路徑、資源的引用都是沒(méi)問(wèn)題的,雖然正常情況下,odex文件不會(huì)對(duì)你的路徑產(chǎn)生干擾,但是也難免odex出現(xiàn)失誤,因?yàn)閷?duì)于odex來(lái)說(shuō),里面的資源無(wú)需保存,生成art文件能夠運(yùn)行即可。合理使用art的配置,可以幫助解決很多問(wèn)題。

以上就是詳解dex優(yōu)化對(duì)Arouter查找路徑的影響的詳細(xì)內(nèi)容,更多關(guān)于dex優(yōu)化 Arouter的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論