美文网首页
深入理解android类加载原理(热更新)

深入理解android类加载原理(热更新)

作者: remax1 | 来源:发表于2020-05-25 14:56 被阅读0次

安卓虚拟机

Dalvik:Dalvik是Google公司用于android平台的java虚拟机。支持已转化为.dex格式的java应用程序的运行。.dex格式是专门为Dalvik应用设计的一种压缩格式,适合内存和处理器速度有限的系统。

ART:Android Runtime,Android 4.4中引入的一个开发者选项,也是Android 5.0及更高版本的默认模式。在应用安装的时候Ahead-Of-Time(AOT)预编译字节码到机器语言。这一机制叫AOT预编译。应用程序安装会变慢,但是执行将更有效率,启动更快。

在Dalvik下,应用程序需要解释运行,常用热点代码通过即时编译器(JIT)将字节码转换为机器码,运行效率低。在ART环境中,应用在安装时,字节码预编译(AOT)成机器码,安装慢了,但是运行效率会变高。

格式

ART会执行AOT,但在Dalvik开发的应用也可以在ART环境下运作。
dexopt:对dex文件进行验证和优化生成odex(Optimized dex)文件
dexAot:在安装时对dex文件文件进行dex优化后为odex文件再进行AOT提前编译操作,编译为OAT可执行文件(机器码)。

ClassLoader

继承关系如图:


图片.png

` BootClassLoader:
用于加载Android Framework层的class文件。

` PathClassLoader:
用与android应用程序内的类加载器。可以加载指定的dex,以及jar/zip/apk中的classes.dex,主要的实现实在BaseDexClassLoader中。

` DexClassLoader
加载指定的dex,以及jar/zip/apk中的classes.dex,主要的实现实在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);

运行结果

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

双亲委托机制

某个类加载器在加载类时,首先将加载任务委托给parent加载器。依次递归,如果parent加载器可以完成类加载任务,就成功返回;只有parent加载器无法加载任务或者没有parent加载器时,才自己去加载。
分析:loadClass在ClassLoader和BootClassLoader才有实现。

protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
      //如果被加载过,直接返回,这就是热更新的原理。
      //将新的dex文件传到dexPathList前面。
        Class<?> clazz = findLoadedClass(className);

        if (clazz == null) {
            ClassNotFoundException suppressed = null;
            try {
              //递归调用父亲的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()方法并调用,生成新的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生成的数组合并,修改dexElement的值

//合并后的数组
Object[] combined ;
System.arraycopy(NewElements, 0, combined, 0, NewElements.length);
        System.arraycopy(OldElements, 0, combined, NewElements.length, OldElements.length);

相关文章

  • 深入理解android类加载原理(热更新)

    安卓虚拟机 Dalvik:Dalvik是Google公司用于android平台的java虚拟机。支持已转化为.de...

  • Android消息机制与类加载

    Android消息机制原理Android类加载Android热修复 Android消息机制    Handler、...

  • 插件化笔记

    看这个就够了啊,深入理解Android插件化技术 插件化技术核心 类的加载机制和反射机制。 类加载 https:/...

  • 腾讯Tinker热更新与阿里SopHix热修复

    Tinker热更新 Tinker是微信的热更新开源方案,附上github地址 如果Android要加载一个类 就会...

  • Java ClassLoader类加载机制(一)原理

    类加载的理论知识 翻了一下《深入理解Java虚拟机》这本书,类加载这块主要涉及到原理和真正的Class加载;本篇算...

  • SparseArray原理分析

    系列文章地址:Android容器类-ArraySet原理解析(一)Android容器类-ArrayMap原理解析(...

  • SparseIntArray原理分析

    系列文章地址:Android容器类-ArraySet原理解析(一)Android容器类-ArrayMap原理解析(...

  • 热修复

    业界首部安卓热修复宝典出炉,阿里技术大牛联袂推荐 下载地址: 深入理解Android热修复技术原理

  • Android插件化小Demo

    今天梳理了下插件化的知识,做了个小Demo,首先梳理下类加载的原理~ 类加载原理 在Android中类的加载是通过...

  • Android_类加载机制之双亲委派

    本文目标 深入理解Android的类加载机制 1.什么是双亲委派 2.双亲委派下的Class文件加载流程 3.An...

网友评论

      本文标题:深入理解android类加载原理(热更新)

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