深入理解android類加載原理(熱更新)

安卓虛擬機(jī)

Dalvik:Dalvik是Google公司用于android平臺(tái)的java虛擬機(jī)衬鱼。支持已轉(zhuǎn)化為.dex格式的java應(yīng)用程序的運(yùn)行钦听。.dex格式是專門為Dalvik應(yīng)用設(shè)計(jì)的一種壓縮格式墩崩,適合內(nèi)存和處理器速度有限的系統(tǒng)应媚。

ART:Android Runtime,Android 4.4中引入的一個(gè)開發(fā)者選項(xiàng)扣讼,也是Android 5.0及更高版本的默認(rèn)模式弥雹。在應(yīng)用安裝的時(shí)候Ahead-Of-Time(AOT)預(yù)編譯字節(jié)碼到機(jī)器語(yǔ)言垃帅。這一機(jī)制叫AOT預(yù)編譯。應(yīng)用程序安裝會(huì)變慢剪勿,但是執(zhí)行將更有效率贸诚,啟動(dòng)更快。

在Dalvik下厕吉,應(yīng)用程序需要解釋運(yùn)行酱固,常用熱點(diǎn)代碼通過(guò)即時(shí)編譯器(JIT)將字節(jié)碼轉(zhuǎn)換為機(jī)器碼,運(yùn)行效率低头朱。在ART環(huán)境中运悲,應(yīng)用在安裝時(shí),字節(jié)碼預(yù)編譯(AOT)成機(jī)器碼项钮,安裝慢了班眯,但是運(yùn)行效率會(huì)變高。

格式

ART會(huì)執(zhí)行AOT烁巫,但在Dalvik開發(fā)的應(yīng)用也可以在ART環(huán)境下運(yùn)作署隘。
dexopt:對(duì)dex文件進(jìn)行驗(yàn)證和優(yōu)化生成odex(Optimized dex)文件
dexAot:在安裝時(shí)對(duì)dex文件文件進(jìn)行dex優(yōu)化后為odex文件再進(jìn)行AOT提前編譯操作,編譯為OAT可執(zhí)行文件(機(jī)器碼)亚隙。

ClassLoader

繼承關(guān)系如圖:


圖片.png

` BootClassLoader:
用于加載Android Framework層的class文件磁餐。

` PathClassLoader:
用與android應(yīng)用程序內(nèi)的類加載器∈研可以加載指定的dex崖媚,以及jar/zip/apk中的classes.dex亦歉,主要的實(shí)現(xiàn)實(shí)在BaseDexClassLoader中。

` DexClassLoader
加載指定的dex畅哑,以及jar/zip/apk中的classes.dex肴楷,主要的實(shí)現(xiàn)實(shí)在BaseDexClassLoader中。

在任意的Activity加入如下代碼

  ClassLoader classLoader = getClassLoader();
        ClassLoader classLoader1 = Activity.class.getClassLoader();

        System.out.println("getClassLoader:"+classLoader);
        System.out.println("getClassLoader 的父親 :"+classLoader.getParent());
        System.out.println("Activity.class :"+classLoader1);

運(yùn)行結(jié)果

getClassLoader:dalvik.system.PathClassLoader[DexPathList[```]]
getClassLoader 的父親 :java.lang.BootClassLoader@1d467fc
Activity.class :java.lang.BootClassLoader@1d467fc

雙親委托機(jī)制

某個(gè)類加載器在加載類時(shí)荠呐,首先將加載任務(wù)委托給parent加載器赛蔫。依次遞歸,如果parent加載器可以完成類加載任務(wù)泥张,就成功返回呵恢;只有parent加載器無(wú)法加載任務(wù)或者沒有parent加載器時(shí),才自己去加載媚创。
分析:loadClass在ClassLoader和BootClassLoader才有實(shí)現(xiàn)渗钉。

protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
      //如果被加載過(guò),直接返回钞钙,這就是熱更新的原理鳄橘。
      //將新的dex文件傳到dexPathList前面。
        Class<?> clazz = findLoadedClass(className);

        if (clazz == null) {
            ClassNotFoundException suppressed = null;
            try {
              //遞歸調(diào)用父親的loadClass
                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;
    }

看看BootClassLoader的loadClass():

protected Class<?> loadClass(String className, boolean resolve)
           throws ClassNotFoundException {
        //找到后直接返回
        Class<?> clazz = findLoadedClass(className);

        if (clazz == null) {
          //為空則自己去加載
            clazz = findClass(className);
        }

        return clazz;
    }

可以看出瘫怜,BootClassLoader重寫了loadClass方法,這里沒有parent屬性本刽。

具體思路

1.首先拿到BaseDexClassLoader里的pathList屬性鲸湃。

···示例代碼
Field pathList= classLoader.getDeclaredField("pathList");

2.找到pathList的makePathElements()方法并調(diào)用子寓,生成新的dexElements暗挑;

···示例代碼
 Method method = clazz.getDeclaredMethod("makeDexElements", parameterTypes);


private static Element[] makeDexElements(List<File> files,File optimizedDirectory,
List<IOException> suppressdExceptions,classLoader loader,boolean is Trussed){
    Element[] elements = new Element[file.size];
}

makeDexElements()中,files就是dex文件别瞭。

3.將原本的 dexElements 與 makePathElements生成的數(shù)組合并窿祥,修改dexElement的值

//合并后的數(shù)組
Object[] combined ;
System.arraycopy(NewElements, 0, combined, 0, NewElements.length);
        System.arraycopy(OldElements, 0, combined, NewElements.length, OldElements.length);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蝙寨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嗤瞎,更是在濱河造成了極大的恐慌墙歪,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贝奇,死亡現(xiàn)場(chǎng)離奇詭異虹菲,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)掉瞳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門毕源,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浪漠,“玉大人,你說(shuō)我怎么就攤上這事霎褐≈吩福” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵冻璃,是天一觀的道長(zhǎng)响谓。 經(jīng)常有香客問(wèn)我,道長(zhǎng)省艳,這世上最難降的妖魔是什么娘纷? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮跋炕,結(jié)果婚禮上赖晶,老公的妹妹穿的比我還像新娘。我一直安慰自己辐烂,他們只是感情好嬉探,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棉圈,像睡著了一般涩堤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上分瘾,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天胎围,我揣著相機(jī)與錄音,去河邊找鬼德召。 笑死白魂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的上岗。 我是一名探鬼主播福荸,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肴掷!你這毒婦竟也來(lái)了敬锐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤呆瞻,失蹤者是張志新(化名)和其女友劉穎台夺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痴脾,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颤介,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滚朵。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冤灾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辕近,到底是詐尸還是另有隱情韵吨,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布亏推,位于F島的核電站学赛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏吞杭。R本人自食惡果不足惜盏浇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芽狗。 院中可真熱鬧绢掰,春花似錦、人聲如沸童擎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)顾复。三九已至班挖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芯砸,已是汗流浹背萧芙。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留假丧,地道東北人双揪。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像包帚,于是被迫代替她去往敵國(guó)和親渔期。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355