一、什么是热修复?
什么是热修复? 定义 : 热修复(HotFix)是以补丁的方式动态修复紧急Bug,不再需要重新发布App,不需要用户重新下载覆盖安装的方式来实现代码的替换修改。
目前主流HotFix方案对比:
二、热修复框架机制
关键技术
类加载机制-双亲委派机制:每一个 ClassLoader 中都有一个 parent 对象,代表的是父类加载器,在加载一个类的时候,会先使用父类加载器去加载,如果在父类加载器中没有找到,自己再进行加载,如果 parent 为空,那么就用系统类加载器来加载。
在加载一个字节码文件时,会询问当前的classLoader是否已经加载过此字节码文件。如果加载过,则直接返回,不再重复加载。如果没有加载过,则会询问它的Parent是否已经加载过此字节码文件,同样的,如果已经加载过,就直接返回parent加载过的字节码文件,而如果整个继承线路上的classLoader都没有加载过,才由child类加载器(即,当前的子classLoader)执行类的加载工作。
Android中最主要的类加载器有如下4个:
- BootClassLoader:加载Android Framework层中的class字节码文件(类似java的Bootstrap ClassLoader)
- PathClassLoader:加载已经安装到系统中的Apk的class字节码文件(类似java的App ClassLoader)
- DexClassLoader:加载制定目录的class字节码文件(类似java中的Custom ClassLoader)
- BaseDexClassLoader:PathClassLoader和DexClassLoader的父类
1)构造函数
public class BaseDexClassLoader extends ClassLoader {
private final DexPathList pathList;
...
public BaseDexClassLoader(String dexPath, File optimizedDirectory, String libraryPath, ClassLoader parent){
super(parent);
this.pathList = new DexPathList(this, dexPCath, libraryPath, optimizedDirectory);
}
...
}
三、Tinker
微信针对QQ空间超级补丁技术的不足提出了一个提供DEX差量包,整体替换DEX的方案。主要的原理是与QQ空间超级补丁技术基本相同,区别在于不再将patch.dex增加到elements数组中,而是差量的方式给出patch.dex,然后将patch.dex与应用的classes.dex合并,然后整体替换掉旧的DEX文件,以达到修复的目的。
具体流程
Dex校验 Tinker在合并完成后,启动应用时,先将放在本地目录下合成后的新dex文件读取出来,然后通过反射获取应用ClassLoader的 dexElements 数组,并将新的dex给合并进去。由于它完全使用了新的dex,这样既不会出现Art地址错乱的问题,在Dalvik环境也无须通过插桩来避免类被打上CLASS_ISPREVERIFYED (因为Tinker合成后的补丁类依旧在原来的dex中,而不是像Qzone那样把补丁类单独放到一个dex去)。
1.BsDiff;它格式无关,但对Dex效果不是特别好,而且非常不稳定。当前微信对于so与部分资源,依然使用bsdiff算法; 2.DexMerge;它主要问题在于合成时内存占用过大,一个12M的dex,峰值内存可能达到70多M; 3.DexDiff;通过深入Dex格式,实现一套diff差异小,内存占用少以及支持增删改的算法。
.首先我们需要将新旧内容排序,这需要针对排序的数组进行操作。 2.新旧两个指针,在内容一样的时候 old、new 指针同时加1,在 old 内容小于 new 内容(注:这里所说的内容比较是单纯的内容比较比如’A’<‘a’)的时候 old 指针加1 标记当前 old 项为删除。 3.在 old 内容大于 new 内容 new 指针加1, 标记当前 new 项为新增。