Android中ClassLoader和java中ClassLoader有什么關(guān)系和不同

一笼呆、Java中的ClassLoader是什么?

? ? ? ?當(dāng)寫好一個Java應(yīng)用程序奶栖,程序都是由若干個.class類文件組織而成的播演,當(dāng)程序在運行時蹬挤,即會調(diào)用該程序的一個入口函數(shù)來調(diào)用系統(tǒng)的相關(guān)功能障般,而這些功能都被封裝在不同的class文件當(dāng)中调鲸,所以經(jīng)常要從這個class文件中要調(diào)用另外一個class文件中的方法,如果另外一個文件不存在的挽荡,則會引發(fā)系統(tǒng)異常藐石。而程序在啟動的時候,并不會一次性加載程序所要用的所有class文件定拟,而是根據(jù)程序的需要于微,通過Java的類加載機制(ClassLoader)來動態(tài)加載某個class文件到JVM中,從而只有class文件被載入到了JVM之后青自,才能被其它class所引用株依。所以ClassLoader就是用來動態(tài)加載class文件到JVM當(dāng)中用的。

簡單的說Java中的ClassLoader就是加載 class 文件延窜,提供給程序運行時使用恋腕。

二、java中ClassLoader加載原理

1逆瑞、原理介紹

ClassLoader使用的是雙親委托模型來搜索類的吗坚,每個ClassLoader實例都有一個父類加載器的引用(不是繼承的關(guān)系,是一個包含的關(guān)系)呆万,虛擬機內(nèi)置的類加載器(Bootstrap ClassLoader)本身沒有父類加載器商源,但可以用作其它ClassLoader實例的的父類加載器。當(dāng)一個ClassLoader實例需要加載某個類時谋减。加載過程是:

? ? ?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是否相同時句各,不僅要判斷兩個類名是否相同吸占,而且要判斷是否由同一個類加載器實例加載的。只有兩者同時滿足的情況下凿宾,JVM才認(rèn)為這兩個class是相同的矾屯。就算兩個class是同一份class字節(jié)碼,如果被兩個不同的ClassLoader實例所加載初厚,JVM也會認(rèn)為它們是兩個不同class件蚕。

? ? ?同一個Class = 相同的 ClassName + PackageName + ClassLoader

如果想了解更加具體請看如下鏈接:

JVM 的工作原理,層次結(jié)構(gòu)以及 GC 工作原理

深入分析Java ClassLoader原理

類加載機制:全盤負責(zé)和雙親委托


三、Android 中的 ClassLoader

? ? Android 的 Dalvik(5.0之前版本)/ART(5.0增加的) 虛擬機如同標(biāo)準(zhǔn) Java 的 JVM 虛擬機一樣,也是同樣需要加載 class 文件到內(nèi)存中來使用排作,但是在 ClassLoader 的加載細節(jié)上會有略微的差別牵啦。

? ? Android打包之后的apk 應(yīng)用,將apk的后綴名改成zip或rar妄痪,解壓之后會看見有一個或多個 class.dex 文件哈雏,用多個dex文件是android使用了MultiDexApplication解決65535的問題。


多個dex文件

android在安裝(installer)apk時衫生,就對dex會進行驗證和優(yōu)化裳瘪,同過一個專門的工具來處理,叫 DexOpt來進行處理障簿,處理之后會產(chǎn)生ODEX文件,運行Apk的時候栅迄,直接加載ODEX站故,避免重復(fù)驗證和優(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類,其具體實現(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)造方法以外就沒有其他的代碼了,具體的實現(xiàn)都是在 BaseDexClassLoader 里面搪桂,其 dexPath 比較受限制糠赦,一般是已經(jīng)安裝應(yīng)用的 apk 文件路徑。

在 Android 中,App 安裝到手機后拙泽,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的委托機制(優(yōu)先父類加載器加載classes蕴纳,由上而下的加載機制会油,防止重復(fù)加載類字節(jié)碼)

android的加載是根據(jù)BaseDexClassLoader子類進行加載不通的dex而子類的實現(xiàn)都在BaseDexClassLoader中,BaseDexClassLoader是關(guān)鍵古毛,下次分析BaseDexClassLoader源碼


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翻翩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子稻薇,更是在濱河造成了極大的恐慌嫂冻,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塞椎,死亡現(xiàn)場離奇詭異桨仿,居然都是意外死亡,警方通過查閱死者的電腦和手機案狠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門服傍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人骂铁,你說我怎么就攤上這事伴嗡。” “怎么了从铲?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵瘪校,是天一觀的道長。 經(jīng)常有香客問我名段,道長阱扬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任伸辟,我火速辦了婚禮麻惶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘信夫。我一直安慰自己窃蹋,他們只是感情好卡啰,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著警没,像睡著了一般匈辱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杀迹,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天亡脸,我揣著相機與錄音,去河邊找鬼树酪。 笑死浅碾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的续语。 我是一名探鬼主播垂谢,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疮茄!你這毒婦竟也來了滥朱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤娃豹,失蹤者是張志新(化名)和其女友劉穎焚虱,沒想到半個月后购裙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體懂版,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年躏率,在試婚紗的時候發(fā)現(xiàn)自己被綠了躯畴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡薇芝,死狀恐怖蓬抄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夯到,我是刑警寧澤嚷缭,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站耍贾,受9級特大地震影響阅爽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荐开,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一付翁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晃听,春花似錦百侧、人聲如沸砰识。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辫狼。三九已至,卻和暖如春观话,著一層夾襖步出監(jiān)牢的瞬間予借,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工频蛔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留灵迫,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓晦溪,卻偏偏與公主長得像瀑粥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子三圆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容