Android的dex熱修復(fù)的實(shí)現(xiàn)基本原理

本文通過(guò)學(xué)習(xí)聊聊 APK —— Dex 熱修復(fù)與 Classpath 總結(jié)

將java文件直接運(yùn)行在JVM和Dalvik中,中講解了java程序如何在JVM和Dalvik中運(yùn)行,其中在Android部分實(shí)現(xiàn)是,先將java文件轉(zhuǎn)為dex文件,導(dǎo)入至安卓手機(jī)中,通過(guò)Dalvik對(duì)該文件編譯運(yùn)行,實(shí)現(xiàn)將java文件運(yùn)行在手機(jī)中功能。本文重點(diǎn)講解如何利用該功能實(shí)現(xiàn)簡(jiǎn)易熱修復(fù)的效果。
熱修復(fù)的根本原理是通過(guò)修改DexClassLoader 中dexPathList 的dex順序,達(dá)到熱修復(fù)的效果。

1.制作帶有bug的dex

首先創(chuàng)建一個(gè)帶有打印bug的類test.java,如下所示:

package xiaohan;
public class Test {
    public  void test (){
        System.out.println("This a BUG!");
    }
}

這里需要注意,由于此類需要在帶有main的類中引用,需要自定義一個(gè)package,否則無(wú)法正常引用該類。

創(chuàng)建一個(gè)帶有main的主類HelloWorld.java,該類中需要引用Test,通過(guò)import的形式引入。

import  xiaohan.Test;
public class HelloWorld {
    public static void main (String [] args){
        Test test = new Test();
        test.test();
    }
}

由于需要加載兩個(gè)java文件,需要通過(guò)以下語(yǔ)句執(zhí)行,注意cp之后有個(gè) “.”的修飾符。

javac -cp . HelloWorld.java Test.java
在這里插入圖片描述

將生成的兩個(gè)class文件,生成一個(gè)dex文件,這例需要注意,如果直接按照之前的語(yǔ)句:

dx --dex --output=xiaohan.dex HelloWorld.class Test.class

則會(huì)出現(xiàn)以下錯(cuò)誤:

E:\ProgramFiles\Android\build-tools\28.0.3>dx --dex --output=xiaohan.dex HelloWorld.class Test.class

PARSE ERROR:
class name (xiaohan/Test) does not match path (Test.class)
...while parsing Test.class
1 error; aborting

原因是由于在創(chuàng)建Test.java文件時(shí),為其指定了包名為xiaohan,與HelloWorld不在同一包下,因此需要?jiǎng)?chuàng)建一個(gè)xiaohan的文件夾,將Test.class拷貝進(jìn)去,然后執(zhí)行如下語(yǔ)句:

dx --dex --output=xiaohan.dex HelloWorld.class xiaohan/Test.class

就會(huì)生成一個(gè)的xiaohan.dex文件,將其拷貝至手機(jī)后,運(yùn)行如下語(yǔ)句:

dalvikvm -cp xiaohan.dex HelloWorld

結(jié)果如下:


在這里插入圖片描述

2. 制作補(bǔ)丁包

重新創(chuàng)建一個(gè)新的test.java文件,修改其內(nèi)容如下:

package xiaohan;
public class Test {
    public  void test (){
        System.out.println("Fix a BUG!");
    }
}

制作一個(gè)新的class文件,注意只需要制作Test.class文件,與HelloWorld.class無(wú)關(guān),制作語(yǔ)句如下,去除“.”,包含HelloWorld因?yàn)樵诰幾g時(shí)會(huì)報(bào)錯(cuò)。

javac -cp HelloWorld.java Test.java
在這里插入圖片描述

將新制作的Test.class文件制作成功獨(dú)立的dex文件,這里命名為new.dex,通過(guò)執(zhí)行如下語(yǔ)句:

dx --dex --output=new.dex  xiaohan/Test.class

該dex的是制作補(bǔ)丁包,只包含test.class文件,不包含HelloWorld.class文件。

將生成的new.dex文件,推送至手機(jī)存放HelloWorld.dex的目錄下,執(zhí)行修復(fù)后的語(yǔ)句,如下所示。

dalvikvm -cp new.dex:xiaohan.dex  HelloWorld

注意,這里需要將補(bǔ)丁包放置前面,然后再添加xiaohan.dex(包含main的dex文件),否則如果先添加new.dex或者不添加,則無(wú)法到達(dá)修復(fù)效果,如下語(yǔ)句。

dalvikvm -cp xiaohan.dex:new.dex  HelloWorld

在這里插入圖片描述
以上只是簡(jiǎn)單的演示在Dalvik虛擬機(jī)中,通過(guò)修改DexClassLoader 中dexPathList 的dex加載順序,實(shí)現(xiàn)修復(fù)的效果,實(shí)際使用中,一般我們的APP是安裝在data/data/包名/ 目錄下, 如果需要熱修復(fù)文件,在制作好補(bǔ)丁文件(補(bǔ)丁.dex文件)后推送至應(yīng)用端,在應(yīng)用使用時(shí),判斷是否有該補(bǔ)丁文件,再通過(guò)反射形式,修改dexPathList中補(bǔ)丁包的順序,實(shí)現(xiàn)APP熱修復(fù)的效果??蓞⒖?a target="_blank">Android學(xué)習(xí)——手把手教你實(shí)現(xiàn)Android熱修復(fù)

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

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

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