美文网首页
Android的dex热修复的实现基本原理

Android的dex热修复的实现基本原理

作者: 晓涵说 | 来源:发表于2019-10-06 17:43 被阅读0次

    本文通过学习聊聊 APK —— Dex 热修复与 Classpath 总结

    将java文件直接运行在JVM和Dalvik中,中讲解了java程序如何在JVM和Dalvik中运行,其中在Android部分实现是,先将java文件转为dex文件,导入至安卓手机中,通过Dalvik对该文件编译运行,实现将java文件运行在手机中功能。本文重点讲解如何利用该功能实现简易热修复的效果。
    热修复的根本原理是通过修改DexClassLoader 中dexPathList 的dex顺序,达到热修复的效果。

    1.制作带有bug的dex

    首先创建一个带有打印bug的类test.java,如下所示:

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

    这里需要注意,由于此类需要在带有main的类中引用,需要自定义一个package,否则无法正常引用该类。

    创建一个带有main的主类HelloWorld.java,该类中需要引用Test,通过import的形式引入。

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

    由于需要加载两个java文件,需要通过以下语句执行,注意cp之后有个 “.”的修饰符。

    javac -cp . HelloWorld.java Test.java
    
    在这里插入图片描述

    将生成的两个class文件,生成一个dex文件,这例需要注意,如果直接按照之前的语句:

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

    则会出现以下错误:

    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
    

    原因是由于在创建Test.java文件时,为其指定了包名为xiaohan,与HelloWorld不在同一包下,因此需要创建一个xiaohan的文件夹,将Test.class拷贝进去,然后执行如下语句:

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

    就会生成一个的xiaohan.dex文件,将其拷贝至手机后,运行如下语句:

    dalvikvm -cp xiaohan.dex HelloWorld
    

    结果如下:


    在这里插入图片描述

    2. 制作补丁包

    重新创建一个新的test.java文件,修改其内容如下:

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

    制作一个新的class文件,注意只需要制作Test.class文件,与HelloWorld.class无关,制作语句如下,去除“.”,包含HelloWorld因为在编译时会报错。

    javac -cp HelloWorld.java Test.java
    
    在这里插入图片描述

    将新制作的Test.class文件制作成功独立的dex文件,这里命名为new.dex,通过执行如下语句:

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

    该dex的是制作补丁包,只包含test.class文件,不包含HelloWorld.class文件。

    将生成的new.dex文件,推送至手机存放HelloWorld.dex的目录下,执行修复后的语句,如下所示。

    dalvikvm -cp new.dex:xiaohan.dex  HelloWorld
    

    注意,这里需要将补丁包放置前面,然后再添加xiaohan.dex(包含main的dex文件),否则如果先添加new.dex或者不添加,则无法到达修复效果,如下语句。

    dalvikvm -cp xiaohan.dex:new.dex  HelloWorld
    
    在这里插入图片描述 以上只是简单的演示在Dalvik虚拟机中,通过修改DexClassLoader 中dexPathList 的dex加载顺序,实现修复的效果,实际使用中,一般我们的APP是安装在data/data/包名/ 目录下, 如果需要热修复文件,在制作好补丁文件(补丁.dex文件)后推送至应用端,在应用使用时,判断是否有该补丁文件,再通过反射形式,修改dexPathList中补丁包的顺序,实现APP热修复的效果。可参考Android学习——手把手教你实现Android热修复

    相关文章

      网友评论

          本文标题:Android的dex热修复的实现基本原理

          本文链接:https://www.haomeiwen.com/subject/ohnupctx.html