Android中的ClassLoader

阿臣發表於2018-03-06

Android中的ClassLoader

簡述 Android中哪幾種ClassLoader?它的作用和區別是什麼?

Android 的 Dalvik/ART 虛擬機器如同標準 Java 的 JVM 虛擬機器一樣,也是同樣需要載入 class 檔案到記憶體中來使用,但是在 ClassLoader 的載入細節上會有略微的差別。

  1. BootClassLoader BootClassLoader 為ClassLoader 內部類,是用來預載入常用類的。在Zygote程式中建立。
  2. PathClassLoader PathClassLoader 為ClassLoader的直接子類,在應用啟動時,從data/app/...目錄下載入APK檔案,他的建構函式也明顯遵循雙親委託模式,具體實現在父類BaseDexClassLoader裡面。一般只載入已安裝的apk檔案
  3. DexClassLoader DexClassLoader 也是BaseDexClassLoader的子類,與PathClassLoader的區別在於 它可以載入除了已安裝的APK檔案也可以加 載SD上的APK檔案,這也是外掛化與熱修復的基礎,在不需要安裝APK的情況下,完成dex的載入

簡述 ClassLoader的雙親委託模型

當類載入器收到載入類或資源的請求時,通常先會判斷自己是否載入過這個請求類或資源,如果自身沒有載入過則委託父類去載入,當父類的基類都沒有載入過這個請求類才會在對應類的路徑尋找Class位元組碼 載入,然後返回,如果沒有則會轉給子類去尋找對應類的路徑,如此反覆直到源ClassLoader,如果源ClassLoader也沒有找到路徑則會報錯

具體步驟如下

  1. 源ClassLoader 首先判斷自身是否載入過 請求類Class,如果載入過就直接返回,否則委託父類載入器
  2. 父類載入器也先判斷自身是否載入過該Class,與源ClassLoader一樣,如果載入過直接返回,沒有就會委託父類的父類載入器繼續這一步驟
  3. 依此類推,直到最上層的父類也沒有載入過請求類,如果沒有就會從該請求類的路徑下尋找Class位元組碼並將檔案載入,載入成功就會直接返回ClassLoader,否則會傳給子類繼續該動作.
  4. 以此內推,直到源ClassLoader 也通過請求類的路徑來尋找該Class位元組碼做載入, 載入成功就會返回請求類的ClassLoader,失敗則會報錯。丟擲異常

簡述 雙親委託模型在熱修復領域的應用

熱修復的實現的一個原理就是通過BaseDexClassLoader的findClass方法 來使DexPathList的findClass方法來處理,在DexPathList的內部則會遍歷DexFile,通過DexFile的dex.loadClassBinaryName來完成類的載入,所以我們只要把補丁檔案放在最前面讓類載入完成並返回,就不會去載入之前舊的類. 又因為BaseDexClassLoader是DexClassLoader的父類及具體實現類,當子類沒有載入請求類的時候就委託父類來進行載入,所以又和我們雙親委託模式息息相關。

參考連結 文件連結

相關文章