類加載機制及熱修復實現之插樁原理

Android中是通過ClassLoader來加載class文件的,Android中的ClassLoader分爲系統的和自定義的

系統的有BootClassLoader  DexClassLoader PathClassLoader,而DexClassLoader PathClassLoader都繼承於BaseDexClassLoader這二個在加載類的時候操作邏輯全在父類BaseDexClassLoader裏面,而不管是系統的還是其它的類加載器都不會複寫基類的loadClass方法,所以每次加載一個類的時候都是基類先處理,找到則返回,沒找到則是其它加載器的findClass方法.

從我們Android打成的apk文件可以看出,裏面是由很多.dex文件組成,一個dex文裏面包含多個class文件.當啓動一個apk的時候會創建出系統級別的加載器也就是PathClassLoader,初始化這個加載器的時候會在構造方法裏創建DexPathList並賦值給BaseClassLoader的成員變量pathList.而在DexPathList的構造方法中會通過makeDexElements方法創建出一個Element數組,每一個Element裏會持有相應的DexFile.

當我們開始要加載一個類的時候,這時會調用基類的loadClass方法,看是否基類裏有,如果都沒有則會調用到PathClassLoader的findClass也就是BaseDexClassLoader的這個方法,裏面會執行他的成員變量pathList的findClass方法,面pathList是DexPathList,在pathList.findClass裏面會遍歷它的成員變量Elements數據,通過Element裏的DexFile文件來實例化出一個Class出來,這個Class不爲Null則返回,爲null則會報ClassNotfindException.

 

而熱修復則是用到了類加載機制原理來實現的,主要是找到hook這裏的hook點是Elements這個數組,因爲每次findClass的時候都會遍歷這個數據,然後通過ELement的Dexfile來找Class找到則返回沒有找到就繼續遍歷,所以我們只需要改變Elements裏面的值將修復好的dex文件也變成Elements數組,然後將新生成的和系統的進行合併,新生成的放在前面,系統的放在後面,這樣每當加載的時候就會先獲取到修復好的class文件,因爲找到了所以不會繼續往後找,所以之前有bug的class就加載不到這樣就達到了修復的效果,但是有個條件就是如果當前類已經被加載了則必然重啓APP纔會有效果.

 

這裏再講下Android的打包流程

首先會通過aapt命令將資源生成一個R.java文件 如果有aild的話還會通過aidl命令將其轉爲對應java文件

然後是javac將所有的.java文件編譯成.class文件.再通過dex腳本將所有的.class文件打包成一個.dex文件

再通過apkbuildr腳本生成一個apk文件最後對這個apk進行簽名

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章