真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android熱修復(fù),Android熱修復(fù)包對應(yīng)哪個

Sophix及熱修復(fù)原理介紹

深入探索Android熱修復(fù)技術(shù)原理這本書主要講解了Android的熱修復(fù)中的熱部署,冷部署以及資源和so庫的修復(fù)技巧。全文主要講Sophix應(yīng)對以上四個方面的技術(shù)解析,不管是自家產(chǎn)品還是業(yè)界其他方案的橫縱對比,Sophix技術(shù)目前都是最優(yōu)的。

成都創(chuàng)新互聯(lián)公司成立與2013年,先為余姚等服務(wù)建站,余姚等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為余姚企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

在事件分發(fā)流中,通過Hook鉤子在事件傳送到終點前截獲并監(jiān)控事件的傳輸,從而處理一些特定干預(yù)事件。

Sophix同時使用了熱啟動的底層替換方案及冷啟動的類加載方案,兩個方案使用的補丁是相同的。優(yōu)先熱啟動。

基本參考InstantRun的實現(xiàn):構(gòu)造一個包含所有新資源的新的AssetManager。并在所有之前引用到原來的AssetManager通過反射替換掉。

Sophix不修改AssetManager的引用,構(gòu)造的補丁包中只包含有新增或有修改變動的資源,在原AssetManager中addAssetPath這個包就可以了。資源包不需要在運行時合成完整包。

本質(zhì)是對native方法的修復(fù)和替換。類似類修復(fù)反射注入方式,將補丁so庫的路徑插入到nativeLibraryDirectories數(shù)據(jù)最前面。

安卓熱更難嗎

熱修復(fù)不難,

但熱修復(fù)因為大量涉及android底層知識,又因為android本身開源,華為vivo小米幾大廠商都可能修改底層相關(guān)代碼,兼容性困難,所以熱修復(fù)技術(shù)開發(fā)維護難度巨大,人力和時間投入不菲。目前主要有騰訊,阿里等幾家互聯(lián)網(wǎng)大廠因自身剛性需求,實現(xiàn)此功能。

目前熱修復(fù)技術(shù)主要有以下幾家:

騰訊系:

QQ超級補丁

**tinker **

阿里系:

Xposed (不支持Art虛擬機,已廢棄)

Andfix (native hook兼容差,適配機型少)

Android類加載機制

Android手寫熱修復(fù)(一)--ClassLoader

我們平時編寫的 .java 文件不是可執(zhí)行文件,需要先編譯成 .class 文件才可以被虛擬機執(zhí)行。所謂類加載是指通過 類加載器 把class文件加載到虛擬機的內(nèi)存空間,具體來說是方法區(qū)。類通常是按需加載,即第一次使用該類時才加載。

首先,Java與Android都是把類加載到虛擬機內(nèi)存中,然后由虛擬機轉(zhuǎn)換成設(shè)備識別的機器碼。但是由于二者使用的虛擬機不同,所以在類加載方面也是有所區(qū)別的。Java的虛擬機是JVM,Android的虛擬機是dalvik/art(5.0以后虛擬機是art,是對dalvik的一種升級)。 Java虛擬機運行的是class文件,而Android 虛擬機運行的是dex文件。 dex其實是class文件的集合,是對class文件優(yōu)化的產(chǎn)物,是為了避免出現(xiàn)重復(fù)的class。

從上面的講解中,我們已經(jīng)知道我們平時寫的類是被 類加載器 加載盡虛擬機內(nèi)存才能運行。下面就通過Framework源碼來為大家講解Android中最主要的5個類加載器。

在Activity做個簡單驗證:

結(jié)果:

可以看出系統(tǒng)類由BootClassLoader加載,apk中的類由PathClassLoader加載,PathClassLoader的父類加載器是BootClassLoader。如果暫時不能理解父類加載器是什么,沒關(guān)系,后面講雙親委托機制的時候會理解的。

下面的源碼解析基于 Android SDK API28 ,這幾個類加載器(除了ClassLoader)沒辦法直接在AS上查看源碼,AS搜索到的是反編譯的class的內(nèi)容,是不可信的,為大家推薦一個在線工具查看, 在線查看Android Framework源碼 。

用來加載本地文件系統(tǒng)上的文件或目錄,通常是用來加載apk中我們自己寫的類,而像 Activity.class 這種系統(tǒng)的類不是由它加載。注意:這里,并不像很多網(wǎng)上文章說的那樣只能加載apk,本地的其他目錄的文件也是可以的,這一點我會在后面驗證說明。

也是被用來加載 jar 、apk、dex,通常用來加載未安裝到應(yīng)用中的文件。注意,它需要一個應(yīng)用私有的可寫的目錄來存放優(yōu)化后的dex文件。千萬不要選擇外部存儲路徑,因為這樣可能會導(dǎo)致你的應(yīng)用遭到注入攻擊。

關(guān)于dex文件優(yōu)化,可能很多人還是不理解,水平有限,我簡單解釋一下,

構(gòu)造器參數(shù)解釋:

關(guān)于optimizedDirectory:

1、這是dex優(yōu)化后的路徑,它必須是一個應(yīng)用私有的可寫的目錄否則會存在注入攻擊的風(fēng)險;

2、這個參數(shù)在API 26(8.0)之前是有值的,之后的話,這個參數(shù)已經(jīng)沒有影響了,因為在調(diào)用父構(gòu)造器的時候這個參數(shù)始終為null,也就是說Android 8.0 以后DexClassLoader和PathClassLoader基本一樣的來;

3、在加載app的時候,apk內(nèi)部的dex已經(jīng)執(zhí)行過優(yōu)化了,優(yōu)化之后放在系統(tǒng)目錄/data/dalvik-cache下。

這個構(gòu)造器的關(guān)鍵是初始化了一個DexPathList對象,這個是后面加載class的關(guān)鍵類。

這個構(gòu)造方法等關(guān)鍵是通過 makeDexElements() 方法來獲取Element數(shù)組,這個Element數(shù)組非常關(guān)鍵,后面查找class就會用到它,也是熱修復(fù)的關(guān)鍵點之一。

splitDexPath(dexPath) 方法是把dexPath目錄下的所有文件轉(zhuǎn)換成一個File集合,如果是多個文件的話,會用 : 作為分隔符。

makeDexElements()

小結(jié)一下,這個方法就是把指定目錄下的文件apk/jar/zip/dex按不同的方式封裝成Element對象,然后按順序添加到Element[]數(shù)組中。

DexPathList#loadDexFile()

可以看到 DexFile 最終是調(diào)用了openDexFile、native方法openDexFileNative去打開Dex文件的,如果outputName為空,則自動生成一個緩存目錄,具體來說是 /data/dalvik-cache/xxx@classes.dex 。openDexFileNative這個native方法就不具體分析了,主要是對dex文件進行了優(yōu)化操作,將優(yōu)化后得odex文件通過mmap映射到內(nèi)存中。感興趣的同學(xué)可以參考:

《DexClassLoader和PathClassLoader加載Dex流程》

現(xiàn)在在回頭看看DexClassLoader與PathClassLoader的區(qū)別。DexClassLoader可以指定odex的路徑,而PathClassLoader則采用系統(tǒng)默認(rèn)的緩存路徑,在8.0以后沒有區(qū)別。

ClassLoader是一個抽象類,有3個構(gòu)造方法,最終調(diào)用的還是第一個構(gòu)造方法,主要功能是保存實現(xiàn)類傳入的parent參數(shù),也就是父類加載器。ClassLoader的實現(xiàn)類主要有2個,一個是前面講過的BaseDexClassLoader,另一個是BootClassLoader。

BootClassLoader是ClassLoader的內(nèi)部類,而且繼承了ClassLoader。

這是加載一個類的入口,流程如下:

1、 先檢查這個類是否已經(jīng)被加載,有的話直接返回Class對象;

2、如果沒有加載過,通過父類加載器去加載,可以看出parent是通過遞歸的方式去加載class的;

3、如果所有的父類加載器都沒有加載過,就由當(dāng)前的類加載器去加載。

通常我們自己寫的類是通過當(dāng)前類加載器調(diào)用 findClass 方法去加載的,但是在 ClassLoader 中這是個空方法,具體的實現(xiàn)在它的子類 BaseDexClassLoader 中。

BaseDexClassLoader # findClass

可以看到是通過pathList去查找class的,這個對象其實之前講過,它是在BaseDexClassLoader 的構(gòu)造方法中初始化的,它實際上是一個 DexPathList 對象。

DexPathList # findClass()

對Element數(shù)組遍歷,再通過Element對象的 findClass 方法去查找class,有的話就直接返回這個class,找不到則返回null。 這里可以看出獲取Class是通過DexFile來實現(xiàn)的,而各種類加載器操作的是Dex。Android虛擬機加載的dex文件,而不是class文件。

1、加載一個類是通過雙親委托機制來實現(xiàn)的。

2、如果是第一次加載class,那是通過 BaseDexClassLoader 中的findClass方法實現(xiàn)的;接著進入 DexPathList 中的findClass方法,內(nèi)部通過遍歷Element數(shù)組,從Element對象中去查找類;Element實際上是對Dex文件的包裝,最終還是從dexfile去查找的class。

3、一般app運行主要用到2個類加載器,一個是PathClassLoader:主要用于加載自己寫的類;另一個是BootClassLoader:用于加載Framework中的類;

4、熱修復(fù)和插件化一般是利用DexClassLoader來實現(xiàn)。

5、PathClassLoader和DexClassLoader其實都可以加載apk/jar/dex,區(qū)別是 DexClassLoader 可以指定 optimizedDirectory ,也就是 dex2oat 的產(chǎn)物 .odex 存放的位置,而 PathClassLoader 只能使用系統(tǒng)默認(rèn)位置。但是在8.0 以后二者是沒有區(qū)別的,只能使用系統(tǒng)默認(rèn)的位置了。

這張圖來源于:

Android虛擬機框架:類加載機制

在類加載流程分析中,我們已經(jīng)知道,查找class是通過DexPathList來完成的,實際上DexPathList最終還是遍歷其Element數(shù)組,獲取DexFile對象來加載Class文件。 由于數(shù)組是有序的,如果2個dex文件中存在相同類名的class,那么類加載器就只會加載數(shù)組前面的dex中的class。如果apk中出現(xiàn)了有bug的class,那只要把修復(fù)的class打包成dex文件并且放在 DexPathList 中Element數(shù)組`的前面,就可以實現(xiàn)bug修復(fù)了 。下一篇為大家?guī)淼氖謱憻嵝迯?fù)。

Android類加載機制的細(xì)枝末節(jié)

從JVM到Dalivk再到ART(class,dex,odex,vdex,ELF)

類加載機制系列2——深入理解Android中的類加載器

Android 熱修復(fù)核心原理,ClassLoader類加載

android 插件化和熱修復(fù)做什么用的

針對Android平臺,Dexposed支持函數(shù)級別的在線熱更新,例如對已經(jīng)發(fā)布在應(yīng)用市場上的宿主APK,當(dāng)我們從crash統(tǒng)計平臺上發(fā)現(xiàn)某個函數(shù)調(diào)用有bug,導(dǎo)致經(jīng)常性crash,這時,可以在本地開發(fā)一個補丁APK,并發(fā)布到服務(wù)器中,宿主APK下載這個補丁APK并集成后,就可以很容易修復(fù)這個crash。

Dexposed是基于久負(fù)盛名的開源Xposed框架實現(xiàn)的一個Android平臺上功能強大的無侵入式運行時AOP框架。

Dexposed的AOP實現(xiàn)是完全非侵入式的,沒有使用任何注解處理器,編織器或者字節(jié)碼重寫器。集成Dexposed框架很簡單,只需要在應(yīng)用初始化階段加載一個很小的JNI庫就可以,這個加載操作已經(jīng)封裝在DexposedBridge函數(shù)庫里面的canDexposed函數(shù)中,源碼如下所示:

/**

* Check device if can run dexposed, and load libs auto.

*/

public synchronized static boolean canDexposed(Context context) {

if (!DeviceCheck.isDeviceSupport(context)) {

return false;

}

//load xposed lib for hook.

return loadDexposedLib(context);

}

private static boolean loadDexposedLib(Context context) {

// load xposed lib for hook.

try {

if (android.os.Build.VERSION.SDK_INT 19){

System.loadLibrary("dexposed_l");

} else if (android.os.Build.VERSION.SDK_INT == 10

|| android.os.Build.VERSION.SDK_INT == 9 ||

android.os.Build.VERSION.SDK_INT 14){

System.loadLibrary("dexposed");

}

return true;

} catch (Throwable e) {

return false;

}

}

Dexposed實現(xiàn)的hooking,不僅可以hook應(yīng)用中的自定義函數(shù),也可以hook應(yīng)用中調(diào)用的Android框架的函數(shù)。Android開發(fā)者將從這一點得到很多好處,因為我們嚴(yán)重依賴于Android SDK的版本碎片化。

android手機廠商為什么不允許熱修復(fù)

因為對手機傷害大。android手機熱修復(fù)不能百分百用戶修復(fù)成功,手機影響極大而且手機很容易出現(xiàn)bug,所以手機廠商不允許熱修復(fù)。


分享名稱:android熱修復(fù),Android熱修復(fù)包對應(yīng)哪個
文章源于:http://weahome.cn/article/phcjsc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部