1、热修复方案
目前市场上的热修复方案可以分为3类:
- class替换
- 字节码插桩
- Native hook
2、class替换
顾名思义,class替换方案就是用修复了bug的class替换有bug的class,了解这种方法我们需要对Java中类的加载有一些了解。类加载中有用到双亲委托加载机制,双亲委托机制就是加载一个类时先通过父亲加载器,往上依次递归,父亲加载不到或没有父亲时,再由自己加载。
一个apk中有多个.dex,dex中有很多.class文件,多个dex文件对应源码中的dexElements数组,加载类时for循环dexElements数组,找到就return,class替换即把修复异常后的.dex插入dexElements的最前面,这时数组中有新旧两Bug.class,加载时加载到修复了异常的bug.class,则直接return,后面的有异常的bug.class则不会加载,从而实现了异常的修复
Tineker原理
dex替换的基础基础上,通过对比差异得出差量包,然后与应用的class.dex合并成新的完整dex,然后替换旧的dex-Elements数组
代表方案:QZone超级补丁、微信Tinker
3. 字节码插桩
字节码插桩原理是在代码编译期给每个方法插入一段代码,这种代码相当于一个开关,如果需要修复,则走新逻辑,完成异常修复;否则走旧逻辑
代表方案:美团Robust
4.Native hook
在native层实现方法结构体的替换
每一个Java方法在art中都对应一个ArtMethod,ArtMethod记录了这个Java方法的所有信息,包括访问权限及代码执行地址等。通过env->FromReflectedMethod得到方法对应的ArtMethod的真正开始地址,然后强转为ArtMethod指针,从而对其所有成员进行修改。
这样以后调用这个方法时就会直接走到新方法的实现中,达到热修复的效果。
代表方案:AndFix、Sophix