热更新你都知道哪些?

1. 什么是热更新

对于“热”这个字从不同的角度会有不同的观点:

  1. 站在app开发者角度的“热”是指在不发版的情况来实现更新。
  2. 从Google提出的“热”是指值无需重新启动。

热更新就是不停机实时更新,HotUpdateHotFix,真正的热更新是不用重启就能更新,在Android 中还不能达到完全的真正热更新。

在热更新出现之前,通过反射注解、反射调用和反射注入等方式已经可以实现类的动态加载了。热更新的实质就是替换,需要替换运行时新的类和资源文件的加载,就可以认为是热操作了。热更新就是一种热操作,它是一种改变app运行行为的技术,其本质就是利用hook操作进行替换,在代码上是一种侵入性的操作。

google和苹果是不支持热更新的,只有在中国特殊国情下才出现了这种黑科技,主要是热更新对程序安全性有一定影响。

2. 为什么需要热更新?

改善用户体验(节省流量、时间、操作程度),快速紧急修复Bug.修复立即生效,是热修复所追求的宗旨。

3. 主流热更新方案?

首先我们需要认知没有完美的热更新方案,只有更好的热更新,热更新不会有100%的成功率。截止2020上半年最强大的热更新方案,我推荐使用Sophix。

热修复因为大量涉及android底层知识,又因为android本身开源,华为vivo小米几大厂商都可能修改底层相关代码,兼容困难。所以热修复技术开发维护难度巨大,人力和时间投入不菲。目前主要有腾讯,阿里等几家互联网大厂因自身刚性需求,实现此功能。

热更新的技术方案我将其分为3种:

  1. 腾讯系的热更新方案Tinker、Qzone。Tinker是腾讯系产品中热更新的主力技术。
  2. 阿里系的热更新技术,Andfix、阿里百川Hotfix1.X、Sophix。我们可以按顺序看作是技术方法的逐步升级。Sophix在技术层结合了Tinker和HotFix,吸取了两者之精华和优势,个人认为截止2020.05是目前最简单实用及稳定强大的热更新技术。
  3. 其他厂的热更新方案如美团点评Robust、饿了么 Amigo
    在这里插入图片描述

4. 热更新的两条常规技术路线

在这里插入图片描述

  1. 类加载替换
    对于类加载在热更新中的使用,请查看我的另一篇博客《热更新之Tinker类加载原理》
  2. 底层替换
    底层替换是一种nativite方案,其操作是在Native修改Filed指针的方式,实现方法的替换,达到即时生效无需重启,对应用无性能消耗的目的。
    在这里插入图片描述
    在类被加载后,类中的每个方法都会在虚拟机中对应ArtMethod,Artmethod记录了这个java方法的所属类、访问权限、代码执行内存地址等信息。通过在运行时利用hook操作native指针,通过这种篡改ArtMethod指针的方式,将补丁方法ArtMethod的成员值逐一赋给旧方法实现替换。所以该种方案能及时生效。

Native修改Filed指针需要在native层进行三步操作:

  • 打开链接库获得操作句柄,获得native层的内部函数,得到ClassObject对象
  • 修改访问权限属性为public
  • 得到新旧方法的指针,新方法指向目标方法,实现方法的替换。

5.QZone热更新

Qzone也是采用的类加载的方案,它修复后是单独放在一个.dex中,插入到dexElements数组的最前面,让虚拟机去加载修复完后的方法。
在这里插入图片描述
这样的热修复有一个大问题就是CLASS_ISPREVERIFIED

当两个调用关系的类不在同一个DEX时,就会产生异常报错。在APK安装时,虚拟机需要将classes.dex优化成odex文件,然后才会执行。
在这个过程中,会进行类的verify操作,如果调用关系的类都在同一个DEX中的话就会被打上CLASS_ISPREVERIFIED的标志,然后才会写入odex文件。

6.Tinker热更新

Tinker热更新方案使用的是基于multidex原理的类加载方法,其详细原理请阅读《热更新之Tinker类加载原理》
Tinker针对Qzone的不足,不再将patch.dex增加到elements数组中,而是差量的方式给出patch.dex,然后将patch.dex与应用的classes.dex合并,然后整体替换掉旧的DEX文件,以达到修复的目的。
在这里插入图片描述

优点:
1.合成整包,不用在构造函数插入代码,防止verify。verify和opt在编译期间就已经完成,不会在运行期间进行
2.性能提高。兼容性和稳定性比较高。
3.Tinker补丁的生成是通过Gradle插件来实现的,打包过程对开发者透明,不需要对包进行额外处理。

不足:
1.与Qzone补丁技术一样,不支持即时生效,必须通过重启应用的方式才能生效(如果是软件启动后才发布的补丁,需要重启两次)。采用了ClassLoader机制
2.需要给应用开启新的进程才能进行合并,并且很容易因为内存消耗等原因合并失败。
3.合并时占用额外磁盘空间,对于多DEX的应用来说,如果修改了多个DEX文件,就需要下发多个patch.dex与对应的classes.dex进行合并操作时这种情况会更严重,因此合并过程的失败率也会更高。
4. Tinker的接入侵入性太高了,打包也麻烦费时间。

7. Andfix热更新

andfix采用的方法替换的热更新方案,其热更新流程。
在这里插入图片描述
Andfix的ArtMethod方法结构是根据Android开源代码写死的,面对国内厂商的定制,经常会导致两者ArtMethod方法结构不一致,这也是兼容问题产生的根本原因。
Andfix优点:

  1. BUG修复的即时性,对应用无侵入,几乎无性能损耗
  2. 补丁包同样采用差量技术,生成的PATCH体积小

不足:

  1. 不支持新增字段,以及修改方法,也不支持对资源的替换。
  2. 由于厂商的自定义ROM,对少数机型暂不支持。

8.Sophix热更新

Sophix是阿里云提供的全平台App热修复服务方案。产品基于阿里巴巴首创hotpatch技术,提供最细粒度热修复能力,让您无需等待实时修复应用线上问题。
Sophix热更新的实质有两种更新方案:底层方法替换+类加载替换。它的补丁包是一种.jar格式。

为了解决Andfix存在的底层替换兼容性问题,Sophix做了一些额外的优化。Sophix通过动态测试ArtMethod的Size(通过c层的mempy(dest、src、size)方法),进行全量拷贝。只要对当前虚拟机中的ArtMethod进行统一拷贝,完成替换就能消除不同虚拟机的导致的Artmethod结构差异。

优点:

  1. Sophix具有底层替换的修改及时性和类加载方案的兼容性,Sophix吸收了百川Hotfix和Tinker的优点于一生,会自动判断在打补丁时选用哪种方案。
  2. Sophix采用非侵入式接入与打包,接入成本低,图形化补丁生成,”傻瓜式接入”。
  3. 阿里提过了补丁管理平台,无需开发者自己在服务器中开发管理功能。
  4. 部分更新无需重启软件,下载的patch极小,相比其他方案,通过两种更新方案,修复成功率极高。

总结

我只使用过基于Bugly的Tinker和阿里的Sophix两种热更新方案。强烈推荐使用Sophix。为什么不推荐使用Bugly呢,虽然是免费的。

  1. Bugly的热更新免费意味着服务质量差,技术QQ支持群百年无响应,别指望能有技术人员来个你答疑。Sophix使用的是钉钉群进行技术支持,技术支持响应速度和态度简直天壤之别。
  2. 服务器时不时就会有崩溃问题,全量更新,热更新不敢使用了,这服务器宕机实在有损大厂威严
  3. 针对同一版本,Bugly集成的Tinker只能打一次补丁,第二次就失败了。Sophix可以对同一版本进行多次补丁修复
  4. Tinker的接入和打包都比较麻烦,代码侵入性高。Sophix接入简单,傻瓜式打包。

额外说明:
阿里有一整套的技术开发生态链,我可以服务器、后台、数据库、移动端测试、推送等都接入阿里云。

博客书写不易,如觉得文章还行,请您点个赞 ^ _ ^ !

相关链接
1. ART与Dalvik、JVM之间的关系你懂了吗?
2. 热更新之Tinker类加载原理
3. 热更新Sophix的爬坑之路

猜你喜欢

转载自blog.csdn.net/luo_boke/article/details/106146604
今日推荐