android的热修复,Android热修复原理
熱修復(fù)框架技術(shù)主要有三類(lèi),代碼修復(fù),資源修復(fù),動(dòng)態(tài)鏈接庫(kù)修復(fù)。
資源修復(fù)
很多資源修復(fù)的框架參考了Instant Run資源修復(fù)的原理,所以先了解一下Instant Run
Instant Run
Instant Run是Android Studio 2.0以后新增的一個(gè)運(yùn)行機(jī)制,能減少開(kāi)發(fā)人員第二次及以后的構(gòu)建和部署時(shí)間。
Hot Swap: 這是效率最高的部署方式,修改一個(gè)現(xiàn)有方法中的代碼會(huì)采用這種方法。它不需要重啟APP, 不需要重啟Activity
Warm Swap: App不需要重啟,但是Activity需要重啟。 修改或刪除一個(gè)現(xiàn)有的資源文件時(shí)采用
Cold Swap: App需要重啟,但不需要重新安裝。 添加,刪除或修改一個(gè)字段和方法,添加一個(gè)類(lèi)時(shí)采用該方式。
Instant Run 資源修復(fù)的原理創(chuàng)建新的AssetManager,通過(guò)反射調(diào)用addAssetPath方法加載外部的資源,這樣新創(chuàng)建的AssetManager就含有了外部資源
將AssetManager類(lèi)型的mAssets字段的引用全部替換為新的AssetManager.
代碼修復(fù)
類(lèi)加載方案
類(lèi)加載方案基于dex分包。 為什么要dex分包,因?yàn)?5535的限制和LinearAlloc限制。65535限制。主要原因是DVM ByteCode的限制,dvm指令集方法調(diào)用指令invoke-kind索引為16bits,最多能引用65535個(gè)方法數(shù)
LinearAlloc限制Dvm中的LinearAlloc是一個(gè)固定的緩沖區(qū),當(dāng)方法數(shù)超出了緩存區(qū)大小就會(huì)報(bào)錯(cuò)。
常用的做法:我們會(huì)新建一個(gè)hotfix分支,然后在該分支上修改bug,生成patch包,然后將patch放到Element數(shù)組dexElements的第一個(gè)元素,這樣就會(huì)優(yōu)先加載patch中的類(lèi),后面存在bug的類(lèi)就不會(huì)被加載。 因?yàn)閏lassloader采用的雙親委托模式,同一個(gè)類(lèi)加載之后就不會(huì)再次加載
類(lèi)加載方案需要重啟app,讓classloader重新加載補(bǔ)丁包中的類(lèi)。為什么要重啟? 因?yàn)轭?lèi)是無(wú)法卸載的,想要重新加載新的類(lèi),就需要重啟app. 所以采用類(lèi)加載方案是不能及時(shí)生效的。Q Q空間超級(jí)補(bǔ)丁,Nuwa,就是按照上面將補(bǔ)丁包放到Element數(shù)組的首位優(yōu)先加載
微信的Tinker將新舊APK做了diff,得到patch.dex,再將patch.dex與手機(jī)APK中的classes.dex做合并,生成新的classes.dex.然后在運(yùn)行時(shí)通過(guò)反射將classes.dex放到Element數(shù)組的第一位。
底層替換方案
底層替換方案不會(huì)再次加載新類(lèi),而是直接在Native層修改原有類(lèi)。底層替換方案主要是替換ArtMethod結(jié)構(gòu)體中的字段或者替換整個(gè)ArtMethod結(jié)構(gòu)體。
AndFix采用的是替換ArtMethod結(jié)構(gòu)體中的字段,但是會(huì)有兼容性問(wèn)題,因?yàn)閺S商會(huì)修改結(jié)構(gòu)體,導(dǎo)致替換失敗
Sophix采用的是替換整個(gè)ArtMethod結(jié)構(gòu)體,不會(huì)存在兼容問(wèn)題。
底層替換方案是可以及時(shí)生效的,不需要重啟。
Instant Run方案主要是通過(guò)ASM來(lái)操作代碼,進(jìn)行方法的修改。
ASM是一個(gè)字節(jié)碼操作框架,能夠動(dòng)態(tài)生成類(lèi)或者增強(qiáng)現(xiàn)有類(lèi)的功能。ASM可以直接產(chǎn)生class文件,也可以在類(lèi)被加載到虛擬機(jī)之前動(dòng)態(tài)改變類(lèi)的行為。
動(dòng)態(tài)鏈接庫(kù)修復(fù)
這個(gè)主要是更新so,也就是重新加載so. 加載so有兩個(gè)方法System的load方法. 該方法傳入的參數(shù)是so在磁盤(pán)空間的完整路徑
System的loadLibrary方法。 該方法傳入的參數(shù)是so的名稱(chēng),用于加載apk安裝后自動(dòng)從APK包中復(fù)制到/data/data/packagename/lib下的so. 目前so的修復(fù)主要是針對(duì)這兩個(gè)方法。
so修復(fù)的兩個(gè)方案將so補(bǔ)丁插入到NativeLibraryElement數(shù)組的前部,讓so補(bǔ)丁優(yōu)先加載
調(diào)用System的load方法來(lái)接管so的加載入口。
參考:
《Android進(jìn)階解密》
總結(jié)
以上是生活随笔為你收集整理的android的热修复,Android热修复原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android viewpager fr
- 下一篇: android导航屏幕,发现具有软件导航