美文网首页
【Android】Android分包热修复原理

【Android】Android分包热修复原理

作者: 代码充电宝 | 来源:发表于2020-01-17 11:00 被阅读0次

(1)原理

  • Android Dex打包原理

1、打包apk的时候,会把java文件通过类加载器编译成class文件,然后把class文件组合成class.dex文件,目的是把不同class文件重复的东西只需保留一份
2、dex文件会把每一个类的id检索起来,存在一个链表里面,这个链表的长度是用short类型存储的,最大值是65536,也就是单个dex文件的方法数上限为65536。方法数包括引用的framwork方法,library方法,还有自己写的代码方法。
3、因为在生成.dex文件之后会生成一些多余的资源,所以系统会对dex文件进行优化,会分配一个缓冲区,缓冲区大小的限制:在android2.x的系统上缓冲区只有5MB,android4.x为8MB或者16MB,如果方法数量超过缓冲区的大小时,会造成dexopt崩溃,所以我们一般apk的方法数要控制在65536以内,如果超出,就要考虑dex分包,api14(Android5.0)之前是不支持分包的

  • Android虚拟机类加载机制

1、Android虚拟机内部使用BaseDexClassLoader/PathClassLoader/DexClassLoader三个类加载器实现(和Java的类加载器不是一个东西),从DEX文件中读取数据,其中PathClassLoader/DexClassLoader继承自BaseDexClassLoader实现的
2、dex文件转换成dexFile对象,存入Element[]数组,findclass顺序遍历Element数组获取DexFile,然后执行DexFile的findclass

// 加载名字为name的class对象
public Class findClass(String name, List<Throwable> suppressed) {
    // 遍历从dexPath查询到的dex和资源Element
    for (Element element : dexElements) {
        DexFile dex = element.dexFile;
        // 如果当前的Element是dex文件元素
        if (dex != null) {
            // 使用DexFile.loadClassBinaryName加载类
            Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
            if (clazz != null) {
                return clazz;
            }
        }
    }
    if (dexElementsSuppressedExceptions != null) {
        suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
    }
    return null;
}
  • 类加载热修复

1、当分包完成之后,会形成一个dex包的有序数组,当需要加载类加载器的时候,会从数组中第一个dex包开始加载,直到找到这个类为止,当多个dex包中都有这个文件的时候,就取第一个文件
2、热修复是通过将已经修复了的bug包打成dex包,并将这个dex包放在有序数组的第一个,当加载类文件的时候,首先会找到修改好的dex包去替换之前存在bug的dex包

相关文章

网友评论

      本文标题:【Android】Android分包热修复原理

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