Android插件基础之类加载器学习
記錄學習java 加載器學習所獲心得,逐步記錄了解java加載器的過程。為了知悉android 插件化的實現(xiàn)原理,從而需要從頭了解android加載apk,以及基礎(chǔ)的java類加載的加載過程情況,為方便記錄和記憶,故此將學習了解的過程記錄成文字,以下文字記錄部分可能來自與多個來源,主體以Java源碼和IBM開發(fā)者博客有關(guān)java加載技術(shù)的博客為主。
Java 類的加載過程
慣性思維,想要了解apk的加載過程,我希望先簡單知道以下Java中對類加載過程的處理(Java一直都是android的官方開發(fā)語言,雖然現(xiàn)在kotlin也是,但原理不變)。首先需要了解Java 類在jvm中的加載過程,基本的流程如下:
裝載
裝載是通過已經(jīng)編譯生成的class文件的位置查找文件獲取其字節(jié)流導入class文件,并將其轉(zhuǎn)換成一個Class類的一個實例,將類的實例存放在jvm的堆區(qū),獲取裝載類的信息到方法區(qū)(屬于jvm的內(nèi)存區(qū)域的一種,主要用于存放類的字段、方法,常量池等信息),這里就是負責處理完成類的加載的過程,主要是由ClassLoader及其子類完成。鏈接
其主要功能就是對類信息格式進行校驗,分配方法區(qū)域的類變量的初始值(并非設(shè)置的初始化數(shù)值,而是初始“0”值)并將類的引用指向?qū)?yīng)類的實例。其內(nèi)部分為三個過程:校驗 —>準備—>解析。執(zhí)行順序為既定的。初始化
初始化類的靜態(tài)變量和靜態(tài)代碼塊(相對于鏈接中的準備階段,將已經(jīng)“初始化”的靜態(tài)數(shù)據(jù)進行真正的初始化).類的初始化情況:
1)遇到類的創(chuàng)建指令New指令
2)java主運行程序的入口類的實例
3)通過反射創(chuàng)建類(newInstance、forClass等)
4)子類初始化觸發(fā)父類的初始化操作
5)java 1.7動態(tài)類型初始化使用和卸載
對創(chuàng)建java對象的操作以及java回收機制對jvm的自動回收卸載。
Java 類加載器
如上,對于java類的加載使用,屬于應(yīng)用層程序員可控過程就只有類的加載過程,通過指定類的加載器來加載我們的類信息,首先通過java的源碼文檔來簡單了解一下類加載的介紹。類加載器位置:
java.lang.ClassLoader.java文檔介紹為:類加載器主要負責加載類的對象,通過給定一個類的“二進制名稱”,那么類加載器會嘗試定位或身成類定義的數(shù)據(jù)信息。一般策略是將二進制名稱轉(zhuǎn)化為一個文件的名稱并加載該類文件的二進制數(shù)據(jù)。數(shù)組類型的類的對象并不是由類加載器創(chuàng)建,而是java 運行時根據(jù)需要自動創(chuàng)建.數(shù)組類型的加載器由Class.getClassLoader()返回.該加載器與其元素類型的類加載器是相同的;如果該元素類型是基本類型,則該數(shù)組類沒有類加載器。
程序可以通過繼承ClassLoader的子類來擴展動態(tài)加載方式.類加載器支持雙親委托模型(通過委托父類查找資源的方式進行操作)查找類或類的資源.虛擬機的內(nèi)置類加載器(稱為 “bootstrap class loader”)本身沒有父類加載器,但是可以將它用作 ClassLoader 實例的父類加載器……
如上,為部分對于ClassLoader的介紹文字.對于通用類加載器通常將其分為四個類型,如下介紹:
引導型類加載器(bootstrap)
該類加載器并沒有父類類加載器,具體實現(xiàn)是通過原生代碼實現(xiàn)(平臺相關(guān)的),用于加載Java的核心代碼,無法直接通過代碼使用.擴展型類加載器
它用來加載 Java 的擴展庫。Java 虛擬機的實現(xiàn)會提供一個擴展庫目錄。該類加載器在此目錄里面查找并加載 Java 類。android中相當于java.lang.BootClassLoader系統(tǒng)類加載器(system class loader)
它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應(yīng)用的類都是由它來完成加載的。可以通過 ClassLoader.getSystemClassLoader()獲取。android 中相當與dalvik.system.PathClassLoader.線程上下文類加載器
用于設(shè)置和獲取線程上下文的類加載器,若是未曾設(shè)置該加載器,線程上下文類加載器將繼承自父線的上下文類加載器,而Java應(yīng)用初始線程上下文類加載器為系統(tǒng)加載器,android中也就是繼承自BaseDexClassLoader的子類加器PathClassLoader或者DexClassLoader加載器.基于Android 平臺對于以上的加載器做一個簡單的代碼測試如下:
Android 中的類加載器
Android 中的虛擬機是由dalvik來實現(xiàn),dalvik并非典型的Java虛擬機。因此,其類的加載器和標準有所不同,對于dalvik而言,其并不可以直接識別加載class文件,而是對class打包成的dex文件進行加載。因此,Android源碼對ClassLoader進行處理,并派生一個子類BaseDexClassLoader,其本質(zhì)類似于jvm中的ClassLoader,確切的說可以說是一個Dex加載器。
基于Android 平臺的類加載器結(jié)構(gòu)如下:
BootClassLoader
是屬于ClassLoader的一個內(nèi)部類,不可直接使用,每個ClassLoader中都存在一個parent(ClassLoader類型),父類加載器,而BootClassLoader屬于最頂層的parent.URLClassLoader
這個是一個輸入jar的加載器,在java中支持在線或本地指定jar文件來加載jar包,但由于android中dalvik并不可以識別class或者jar,只能加載dex,所以并不可以直接使用URLClassLoader來加載jar文件BaseDexClassLoader
這個屬于加載dex文件的加載器的實現(xiàn),具體的加載邏輯在其中實現(xiàn)
PathClassLoader
繼承自BaseDexClassLoader,為默認apk安裝使用的類加載器,會自動尋址apk安裝后默認解壓后的dex路徑,目前dalvik并不支持使用PathClassLoader來加載未安裝的apk,但也有文章說art可以實現(xiàn),暫未驗證,不能確認。DexClassLoader
繼承自BaseDexClassLoader,可以直接加載dex,壓縮文件(apk文件),jar文件,是實現(xiàn)android插件化一個重要的元素,可以幫我們完成對為安裝的插件apk的加載過程.
android基本加載知識記錄,已留備存。
Enjoytoday,EnjoyCoding
轉(zhuǎn)載于:https://www.cnblogs.com/amiko/p/7906204.html
總結(jié)
以上是生活随笔為你收集整理的Android插件基础之类加载器学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript基础和js概括
- 下一篇: little tricks(持续更新)【