android中的類加載

主要介紹幾個知識點:

參考資料

java中常用的classLoader

說到android中的classLoader,就不能不先說說java中的classLoader是什么。
所謂classLoader就是負(fù)責(zé)將編譯好的class文件加載到指定位置的實現(xiàn)類。具體來說,我們編寫java代碼時,需要將其編譯成.class文件,最終運行時就需要將這些class文件加載到內(nèi)存才能運行,而加載這些class文件的方法就可以成為classLoader。
在java中常用的classLoader有以下三種:

Bootstrap Classloder

這個類加載使用C++語言實現(xiàn),是虛擬機(jī)自身的一部分。他是三個類加載器中最頂層的加載類,主要負(fù)責(zé)加載%JAVA_HOME%/lib下的核心類或者jar加載到內(nèi)存中。(值得注意的是,Bootstrao Loader被設(shè)計成只能加載包名為java、javax、sun等開頭的類.)

Extention Classloder

擴(kuò)展類的加載器,由java語言實現(xiàn),主要負(fù)載加載%JAVA_HOME%/lib/ext目錄下的類庫,或者是系統(tǒng)指定的類庫。

AppClassloader

主要負(fù)責(zé)加載系統(tǒng)類路徑或者指定路徑下的類庫。
以上三種是java中定義的ClassLoader。

下面介紹android中常用的類加載器。

classLoader

所有的classLoader的基類,他是一個抽象類,所有的classLoader最終都會繼承自他,我們?nèi)绻枰远xclassLoader也需要直接或者間接的繼承他,并實現(xiàn)其中的findClass方法,并通過defineClass創(chuàng)建一個類實例。自定義類加載的示例如下:

 class NetworkClassLoader extends ClassLoader {
         String host;
          int port;
 
          public Class findClass(String name) {
              byte[] b = loadClassData(name);
              return defineClass(name, b, 0, b.length);
          }
 
          private byte[] loadClassData(String name) {
              // load the class data from the connection
              //省略
          }
      }

BaseDexClassLoader

BaseDexClassLoader繼承自ClassLoader,只是對其進(jìn)行了進(jìn)一步的封裝,并沒有實現(xiàn),他有兩個直接的子類PathClassLoaderDexClassLoader。
簡單介紹一下他的構(gòu)造函數(shù):

    public BaseDexClassLoader(String dexPath, File optimizedDirectory, String librarySearchPath, ClassLoader parent) {
      //dexPath 代表目標(biāo)類所在的apk、DEX或者JAR文件的路徑
      //optimizedDirectory用于指定解壓出來的dex文件存放的路徑
      //librarySearchPath用于指定類中所使用的C/C++庫存放的路徑
      //parent 用于指定該加載器的父加載器,一般為當(dāng)前執(zhí)行類的加載器
    }

關(guān)于BaseDexClassLoader還有一點要補(bǔ)充的是,由于dex文件被包含在APK或者jar文件中,因此在加載目標(biāo)類之前需要先從APK或者jar文件中加壓處dex文件,optimizedDirectory即為指定解壓出來的dex文件存放的路徑,這也是對apk中dex根據(jù)平臺ODEX優(yōu)化的過程。

DexClassLoader

DexClassLoader用于加載包含dex的JAR或者APK文件,但是他不能加載jar或者apk文件。他最終加載的都是dex文件,雖然他是從.jar或者.zip,.apk等結(jié)尾的文件中加載,但是他們最終都會生成一個對應(yīng)的dex文件,他操作的還是dex文件。DexClassLoader繼承自BaseDexClassLoader,原理如下:

public class DexClassLoader extends BaseDexClassLoader {
    public DexClassLoader(String dexPath, String optimizedDirectory,
            String libraryPath, ClassLoader parent) {
        super(dexPath, new File(optimizedDirectory), libraryPath, parent);
    }
}

由代碼不能看出,DexClassLoader只是簡單的對BaseDexClassLoader進(jìn)行了一層封裝,并且指定了optimizedDirectory的路徑為一個新的文件路徑,DexClassLoader通過指定自己的optimizedDirectory,所以它可以加載外部的dex,因為這個dex會被復(fù)制到內(nèi)部路徑的optimizedDirectory。
所以,DexClassLoader一般用來作為動態(tài)加載的加載器。

PathClassLoader

PathClassLoader也是繼承自BaseDexClassLoader,他主要用于加載apk,一般應(yīng)用于加載android的系統(tǒng)類和app應(yīng)用的類。他的實現(xiàn)如下:

public class PathClassLoader extends BaseDexClassLoader {
    public PathClassLoader(String dexPath, ClassLoader parent) {
        super(dexPath, null, null, parent);
    }

    public PathClassLoader(String dexPath, String libraryPath,
            ClassLoader parent) {
        super(dexPath, null, libraryPath, parent);
    }
}

可以看到,PathClassLoader將optimizedDirectory置為null,而optimizedDirectory是用來指定apk或者jar解壓出來的dex存放的位置,如果optimizedDirectory為null,則使用其默認(rèn)路徑/data/dalvik-cache,因此無法加載外部的apk的dex,只能加載內(nèi)部的dex,這些大都是存在系統(tǒng)中已經(jīng)安裝過的apk里面的。

URLClassLoader

URLClassLoader只能加載jar文件,但是dalvik虛擬機(jī)不能識別jar,所以在android中無法使用這個加載器。

InMemoryDexClassLoader

InMemoryDexClassLoader也是繼承自BeseDexClassLoader,是API26新增的加載器,用于加載內(nèi)存中的dex文件。

DelegateLastClassLoader

DelegateLastClassLoader繼承自PathClassLoader,是API27新增的加載器,用于指定最后的查找策略,查找順序如下:先判斷自己是否加載此類,然后在判斷此類的加載器是否加載過此類,最后委托給指定的父加載器。

classloader的雙親委托模型

classLoader雙親委托模型,當(dāng)要加載某個類時,先判斷自己是否有加載過此類,如果自己沒有加在過此類的話,進(jìn)而判斷父類是否加載過,如果某個父類加在過這個類的話,就直接返回,不重復(fù)加載。如果一直到頂級父類都沒有加載此類的話,這個加載任務(wù)就會分發(fā)下來,最后用當(dāng)前類加載器去加載該類。

類加載機(jī)制實現(xiàn)熱修復(fù)方案

通過使用dexClassloader動態(tài)修改加載dex的順序即可達(dá)到熱修復(fù)的目的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容