Android之ClassLoader的工作機制


ClassLoader雙親代理模型加載類的特點及作用

JVM以及Dalvik均是通過ClassLoader加載類,其源碼如下
protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
Class<?> clazz = findLoadedClass(className);

if (clazz == null) {
ClassNotFoundException suppressed = null;
try {
clazz = parent.loadClass(className, false);
} catch (ClassNotFoundException e) {
suppressed = e;
}

if (clazz == null) {
try {
clazz = findClass(className);
} catch (ClassNotFoundException e) {
e.addSuppressed(suppressed);
throw e;
}
}
}

return clazz;
}
從源碼分析可知loadClass方法先判斷是否被loaded過,沒有則通過parent加載,如此遞歸向上,稱之位雙親委托。如果繼承向上的路線中均沒有被加載,才由當前ClassLoader負責加載。
特點:若某個類被根節點加載過,則在以后系統的整個生命周期內不會被重新加載。
作用:
    1.共享:Framework層級的類一旦被根節點加載就緩存在內存,以后不需重新加載。
    2.隔離:不同繼承路線上的classLoader加載的類肯定不是同一個類,這樣做可避免冒充核心庫類,從而訪問核心庫包可見成員。例如,用戶無法通過自定義java.lang.String類,來把系統的String類給替換掉。

Android應用中的ClassLoader對象

在Activity的onCreate方法中調用
ClassLoader classLoader = getClassLoader();
if (classLoader != null) {
lg.e("當前類對應的ClassLoader:" + classLoader.toString());
while (classLoader.getParent() != null) {
classLoader = classLoader.getParent();
lg.e("上個ClassLoader的父親:" + classLoader.toString());
}
}
輸出結果如下,

其中,BootClassLoader在系統啟動時創建,PathClassLoader在應用啟動時創建,用於加載/data/app/com.coca.androidunitylab-1.apk。因此在一個應用中至少有兩個classLoader。


DexClassLoader與PathClassLoader的異同

適用場景:
     DexClassLoader可以加載jar/apk/dex,可以從SD卡中加載未安裝的apk;
    PathClassLoader只能加載系統中已經安裝過的apk;
兩者的區別在於 optimizedDirectory參數,其在 BaseDexClassLoader構造方法中用於構建 DexPathList對象。
optimizedDirectory用來緩存需要加載的dex文件,並創建一個DexFile對象;如果它為null,那么會直接使用dex文件原有的路徑來創建DexFile對象。 optimizedDirectory必須是內部存儲路徑 DexClassLoader由於可以指定 optimizedDirectory,從而可以加載外部dex,在使用的時候被復制到內部路徑 optimizedDirectory內;而 PathClassLoader沒指定 optimizedDirectory,因此只能加載內部dex文件(即已經安裝的apk文件)。
















免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM