Android的Dex動態加載

動態加載dex這個技術屬於看上去高大上,原理很簡單,做起來很崩潰的一個玩意。

首先要說的是,這個技術肯定是得掌握才行的。APK加固,熱修復,插件化,這些個最近幾年比較高大上的玩意,基礎原理都是從動態加載dex開始的。有很多博客做過這個課題,有很多寫的不錯的博客,我就從自己學習的流程給大家說說這玩意。

apk編流程譯

首先要理解APK的一個編譯流程,google的官網上有着詳細的一張圖,我選了一個博客上精簡過的。

                                                           

打包整體流程:

  1. 打包資源文件,生成R.java文件
  2. 處理aidl文件,生成相應的.java文件
  3. 編譯工程源xs碼,生成相應的class文件
  4. 轉換所有的class文件,生成classes.dex文件
  5. 打包生成apk
  6. 對apk文件進行簽名
  7. 對簽名後的apk進行對齊處理

需要注意點的就是appt打包時候是運行兩次,一次編譯是將class文件變成.dex一次是把資源文件編譯出來。

dex文件的65535根本原因是,dex中統計method個數的類型是個short!無符號邊界的話就是就是可以存儲最大65535個方法數。

dex文件的結構

  1. 8位字節的二進制流文件
  2. 各個數據緊密排列,無間隙,減少了文件體積,加快加載速度
  3. 整個工程的類信息都存放在一個dex文件中(不考慮dex分包的情況下)

優勢 :1.優化常量池 2.dex文件的頭文件與索引區部分,dvm可通過這兩部分快速查找到對應類及數據

類加載器

這個玩意就是動態加載的核心了

Android加載器

1.PathClassLoader用來加載Android系統類和應用的類和已安裝好的APK

2.DexClassLoader支持加載APK、DEX和JAR,也可以從SD卡進行加載。

說幾個比較需要注意的點。這兩個類加載器的區別在於,DexClassLoader可以傳遞一個叫optimizedDirectory的參數。從名字上的意思是提供一個存放優化後Dex的文件夾。Dex會經過一次優化,變成ODex,方便內存查找。意思就是DexClassLoader可以解壓,PathClassLoader不帶解壓功能,所以只能加載已安裝好的APK,因爲安裝好的在緩存中有ODex。

另外一個重點就是類加載器是一個雙親委派機制。在加載一個類的時候,它會先讓它的父類去加載,如果父類沒有加載過,纔會自己去加載。作用就是,不會有重複的類被加載。這個機制很關鍵,QQ空間的熱修復方式就是利用了這點。他們把修復類放到Elements數組最前面,這樣有bug的Class就會因爲這個機制,不再被加載,就達到了修復的目的、

 

                                         

反射機制

這就是動態加載的另一個重要機制了。我一直相信,做好android一定要學好JAVA。用個人理解來說下原理:Java中一個.Class文件就是一個類,JVM是動態加載,一個.Class在被使用時纔會加載進內存中。當它被加載到內存後,分配空間還有它的引用。反射就是讓內存在已經加載的通過包名,類名去找到這個.Class文件,找到後返回它的引用。所以這個過程很耗資源。

如何寫一個反射的代碼網上很多,我就只聊一下我的理解。

Android中去動態加載時,記住先去用DexClassLoader把Dex加載完成,再去反射你要的類。如果要進行修復,那就去獲取Elements數組,把你的Dex與之前的Dex重新組合。加固的話就是先把Dex進行加密,然後在Application裏面,先解密,解密完成之後,在把Dex拼起來。

 

 

 

 

 

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