android classloader的功能和工作模式,Android中ClassLoader和java中ClassLoader有什么关系和不同...
一、Java中的ClassLoader是什么?
當(dāng)寫好一個Java應(yīng)用程序,程序都是由若干個.class類文件組織而成的,當(dāng)程序在運(yùn)行時,即會調(diào)用該程序的一個入口函數(shù)來調(diào)用系統(tǒng)的相關(guān)功能,而這些功能都被封裝在不同的class文件當(dāng)中,所以經(jīng)常要從這個class文件中要調(diào)用另外一個class文件中的方法,如果另外一個文件不存在的,則會引發(fā)系統(tǒng)異常。而程序在啟動的時候,并不會一次性加載程序所要用的所有class文件,而是根據(jù)程序的需要,通過Java的類加載機(jī)制(ClassLoader)來動態(tài)加載某個class文件到JVM中,從而只有class文件被載入到了JVM之后,才能被其它c(diǎn)lass所引用。所以ClassLoader就是用來動態(tài)加載class文件到JVM當(dāng)中用的。
簡單的說Java中的ClassLoader就是加載 class 文件,提供給程序運(yùn)行時使用。
二、java中ClassLoader加載原理
1、原理介紹
ClassLoader使用的是雙親委托模型來搜索類的,每個ClassLoader實(shí)例都有一個父類加載器的引用(不是繼承的關(guān)系,是一個包含的關(guān)系),虛擬機(jī)內(nèi)置的類加載器(Bootstrap ClassLoader)本身沒有父類加載器,但可以用作其它ClassLoader實(shí)例的的父類加載器。當(dāng)一個ClassLoader實(shí)例需要加載某個類時。加載過程是:
1.源 ClassLoader 先判斷該 Class 是否已加載,如果已加載,則直接返回 Class,如果沒有則委托給父類加載器。
2.父類加載器判斷是否加載過該 Class,如果已加載,則直接返回 Class,如果沒有則委托給祖父類加載器。
3.依此類推,直到始祖類加載器(引用類加載器)。
4.始祖類加載器判斷是否加載過該 Class,如果已加載,則直接返回 Class,如果沒有則嘗試從其對應(yīng)的類路徑下尋找 class 字節(jié)碼文件并載入。如果載入成功,則直接返回 Class,如果載入失敗,則委托給始祖類加載器的子類加載器。
5.始祖類加載器的子類加載器嘗試從其對應(yīng)的類路徑下尋找 class 字節(jié)碼文件并載入。如果載入成功,則直接返回 Class,如果載入失敗,則委托給始祖類加載器的孫類加載器。
6.依此類推,直到源 ClassLoader。
7.源 ClassLoader 嘗試從其對應(yīng)的類路徑下尋找 class 字節(jié)碼文件并載入。如果載入成功,則直接返回 Class,如果載入失敗,源 ClassLoader 不會再委托其子類加載器,而是拋出異常。
jdk源碼中的ClassLoader
2、JVM中是如何判定兩個class是相同的呢?
JVM在判定兩個class是否相同時,不僅要判斷兩個類名是否相同,而且要判斷是否由同一個類加載器實(shí)例加載的。只有兩者同時滿足的情況下,JVM才認(rèn)為這兩個class是相同的。就算兩個class是同一份class字節(jié)碼,如果被兩個不同的ClassLoader實(shí)例所加載,JVM也會認(rèn)為它們是兩個不同class。
同一個Class = 相同的 ClassName + PackageName + ClassLoader
如果想了解更加具體請看如下鏈接:
三、Android 中的 ClassLoader
Android 的 Dalvik(5.0之前版本)/ART(5.0增加的) 虛擬機(jī)如同標(biāo)準(zhǔn) Java 的 JVM 虛擬機(jī)一樣,也是同樣需要加載 class 文件到內(nèi)存中來使用,但是在 ClassLoader 的加載細(xì)節(jié)上會有略微的差別。
Android打包之后的apk 應(yīng)用,將apk的后綴名改成zip或rar,解壓之后會看見有一個或多個 class.dex 文件,用多個dex文件是android使用了MultiDexApplication解決65535的問題。
多個dex文件
android在安裝(installer)apk時,就對dex會進(jìn)行驗(yàn)證和優(yōu)化,同過一個專門的工具來處理,叫 DexOpt來進(jìn)行處理,處理之后會產(chǎn)生ODEX文件,運(yùn)行Apk的時候,直接加載ODEX,避免重復(fù)驗(yàn)證和優(yōu)化,加快了Apk的響應(yīng)時間。
總之,Android 中的 Dalvik/ART 無法像 JVM 那樣直接加載 class 文件和 jar 文件中的 class,需要通過工具來優(yōu)化轉(zhuǎn)換成 Dalvik byte code 才行,只能通過 dex 或者包含 dex 的jar、apk 文件來加載(注意 odex 文件后綴可能是 .dex 或 .odex,也屬于 dex 文件),因此 Android 中的 ClassLoader 工作就交給了 BaseDexClassLoader 來處理。
BaseDexClassLoader 及其子類
從ClassLoader的android源碼看ClassLoader是一個abstract類,其具體實(shí)現(xiàn)的子類有BaseDexClassLoader和SecureClassLoader。
ClassLoader部門源碼
SecureClassLoader 的子類是URLClassLoader,其只能用來加載 jar 文件,這在 Android 的 Dalvik/ART 上沒法使用的。
BaseDexClassLoader 的子類是PathClassLoader和DexClassLoader。
PathClassLoader
PathClassLoader 在應(yīng)用啟動時創(chuàng)建,從 data/app/… 安裝目錄下加載 apk 文件
PathClassLoader源碼
dexPath:文件或者目錄的列表,dex,apk,多個以文件分隔符分隔,默認(rèn)是“.”
librarySearchPath:包含lib庫的目錄列表,多個以文件分隔符分隔,默認(rèn)是空格
parent:父類加載器
PathClassLoader 里面除了這 2 個構(gòu)造方法以外就沒有其他的代碼了,具體的實(shí)現(xiàn)都是在 BaseDexClassLoader 里面,其 dexPath 比較受限制,一般是已經(jīng)安裝應(yīng)用的 apk 文件路徑。
在 Android 中,App 安裝到手機(jī)后,apk 里面的 class.dex 中的 class 均是通過 PathClassLoader 來加載的。
DexClassLoader
A class loader that loads classes from.jar and.apk files containing aclasses.dexentry. This can be used to execute code not installed as part of an application.
根據(jù)官方給出的文檔 DexClassLoader 可以從 SD 卡上加載包含 class.dex 的 .jar 和 .apk 文件,這也是插件化和熱修復(fù)的基礎(chǔ),在不需要安裝應(yīng)用的情況下,完成需要使用的 dex 的加載。
DexClassLoader源碼
DexClassLoader類就只有一個方法,改方法有四個個參數(shù)
dexPath:dex文件路徑列表,多個路徑使用”:”分隔
dexOutputDir:經(jīng)過優(yōu)化的dex文件(odex)文件輸出目錄
libPath:動態(tài)庫路徑(將被添加到app動態(tài)庫搜索路徑列表中)
parent:這是一個ClassLoader,這個參數(shù)的主要作用是保留java中ClassLoader的委托機(jī)制(優(yōu)先父類加載器加載classes,由上而下的加載機(jī)制,防止重復(fù)加載類字節(jié)碼)
android的加載是根據(jù)BaseDexClassLoader子類進(jìn)行加載不通的dex而子類的實(shí)現(xiàn)都在BaseDexClassLoader中,BaseDexClassLoader是關(guān)鍵,下次分析BaseDexClassLoader源碼
總結(jié)
以上是生活随笔為你收集整理的android classloader的功能和工作模式,Android中ClassLoader和java中ClassLoader有什么关系和不同...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 7.0 裁剪,Andro
- 下一篇: i219v linux,I219V高传播