热修复原理分析总结

热修复概念

当应用出现bug的时候,可以帮助我们在不进行重新安装应用的情况下实现对bug的修复的能力

热修复流程步骤

在这里插入图片描述

常见热修复解决方案


可以注意到Tinker和QZone 是通过类替换的方式来实现热修复,而AndFix和Robust不是通过类替换的方式来实现的;
另外通过类替换的方式来实现热修复的两个框架Tinker和QZone,是不能即时生效的,必须重启后生效

类替换方案

Qzone
原理:基于Multidex分包方案,将解决后的类打进一个单独的dex补丁包,放入Elements数组的最前面,当ClassLoader查找类的时候,会按照顺序遍历Elements数组,理论上如果在不同dex中有相同的类,ClassLoader会优选选择排在前面的dex文件中的类。
在这里插入图片描述

差分算法+类替换方案

Tinker
原理:运行的时候,启动一个新进程(耗时),通过dexdiff算法计算对比bug.apk和fix.apk中dex的区别生成fix.dex补丁包,在运行时将bug.apk的dex与补丁包合成,重启后通过ClassLoader加载合成后的dex,完成修复
在这里插入图片描述
由于Android N混合编译的影响,常用代码会被编译成art文件,这个art文件会在apk启动时会加入到PathClassloader的ClassTable中,系统在查找类的时候会先查找base.art中的,根据类加载机制,加载过的class不会被再次加载,所以补丁包中的dex文件不会被加载。
在这里插入图片描述
Tinker采用运行时替换PathClassLoader的方案,废弃art文件,当应用启动的时候,通过新的PathClassLoader加载
参考 Android N混合编译与对热补丁影响解析

native hook方案

AndFix
原理:在native层动态替换java层的方法,在native层将方法的成员一个一个的替换,由于是在动态的替换方法,所以不需要重启,是即时生效的
缺点:

需要针对dalvik虚拟机和art虚拟机做适配,需要考虑指令集的兼容问题,需要native代码支持,兼容性上会有一定的影响

查看下图源码片段,源码中将方法中有bug的成员替换成了fix之后的成员,而且针对dllvik虚拟机和art虚拟机做了适配
在这里插入图片描述
Sophix
原理:在native层利用memcpy(des,src,sizeof(ArtMethod))直接替换有bug的方法,不用关心artMethod的具体实现,所以解决了兼容性问题。

字节码插桩方案

Robust
原理:利用字节码插桩,对每个函数在编译打包阶段自动插入了一段代码,类似于代理,将方法执行的代码重定向到其它方法中
流程:
在这里插入图片描述

public static ChangeQuickRedirect changeQuickRedirect;
//有问题的代码
@Modify //改动代码后手动添加注解用于补丁包的生成
public long getIndex() {
	return 100;
}

//经过插桩后实际执行的代码
public long getIndex {
	if(changeQuickRedirect != null) {
			return 修复后的代码;
	}
	return 100;
}

Robust为每个class增加了个类型为ChangeQuickRedirect的静态成员,而在每个方法前都插入了使用changeQuickRedirect相关的逻辑,当 changeQuickRedirect不为null时,可能会执行到accessDispatch从而替换掉之前老的逻辑,达到即时fix的目的。

总结

1.Tinker和QZone都是利用类替换的修复方式,区别是Tinker是利用差分算法生成记录有修复前和修复后差分信息的dex,QZone是修复后的完整dex,一定程度上查分信息dex的大小是优于完整dex的。二者都是重启后生效;
2.AndFix native层进行成员的替换,兼容性较差,已经不维护了,能即时生效
3.Robust 利用字节码插桩,对每个函数在编译打包阶段自动插入了一段代码,类似于代理;能即时生效

热修复需要了解的技术,可以看看我的另一篇文章
Android中ClassLoader双亲委托机制

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值