推荐 | 移动开发主流热更新技术
在 App 开发中,关于热更新的话题关于热修复的话题越来越多,随着技术的迭代,各种框架的发展更新,热更新的框架已经日趋成熟,各大互联网公司基本都有研发热更新框架,方案实现及优缺点各有差异,但总的来说有三大类。
ClassLoader 加载方案:代表有 Qzone 的超级补丁、大众点评的 nuwa、百度金融的 rocooFix,、以及美团的 robust。
Native 层替换方案:代表有阿里的 Dexposed、AndFix 与腾讯的内部方案 KKFix;
H5/小程序动态加载:代表有 HTML5 方案、FinClip 小程序容器热更新方案;
接下来分别为大家介绍几个极具代表性的方案,以及它们的优缺点:
1、QZone 的热更新方案
QZone 方案推出比较早,对热修复技术的推进很有启发意义。它是基于 Android dex 分包方案,最关键的技术点在于利用字节码插桩的方式绕开了预校验问题。这种方案只支持 App 重启之后才能修复,也就是 App 在运行的时候加载到了补丁包也不能及时修复,需要 App 重新启动的时候才会修复,这是因为 QZone 方案是基于类加载区需要重新加载补丁类才能实现的,所以必须进行重启才能修复。此外,QZone 方案只支持到类结构本身代码层面的修复,不支持资源的修复。
原理
class 加载原理:dex 文件转换成 dexFile 对象,存入 Element[]数组,findclass 顺序遍历 Element 数组获取 DexFile,然后执行 DexFile 的 findclass。
Hook 了 ClassLoader.pathList.dexElements[],将补丁的 dex 插入到数组的最前端,所以会优先查找到修复的类,从而达到修复的效果。
优点
代码是非侵入式的,对 apk 体积影响不大。
缺点
需要下次启动才修复。
性能损耗大,为了避免类被加上 CLASS_ISPREVERIFIED,使用插桩,单独放一个帮助类在独立的 dex 中让其他类调用。
2、微信 Tinker
据微信内部人士介绍:微信 tinker 项目之初最大难点在于如何突破 Qzone 方案的性能问题,通过研究 Instant Run 的冷插拔与 buck 的 exopackage 找到灵感。它们的思想都是全量替换新的 Dex 因为使用全新的 dex,所以自然绕开了 Art 地址可能错乱的问题,在 Dalvik 模式下也不需要插桩,加载全新的合成 dex 即可。
原理
采用 dex 替换的方式,避免了 dex 插桩带来的性能损耗。原理是提供 dex 差量包,整体替换 dex 的方案。差量的方式给出 patch.dex,然后将 patch.dex 与应用的 classes.dex 合并成一个完整的 dex,完整 dex 加载得到 dexFile 对象作为参数构建一个 Element 对象然后整体替换掉旧的 dex-Elements 数组。
Tinker 自研了 DexDiff/DexMerge 算法,对于 dex 文件的处理经验老道。Tinker 还支持资源和 So 包的更新,So 补丁包使用 BsDiff 来生成,资源补丁包直接使用文件 md5 对比来生成,针对资源比较大的(默认大于 100KB 属于大文件)会使用 BsDiff 来对文件生成差量补丁。
优点
兼容性高、补丁小。
开发透明,代码非侵入式。
支持 so 文件、资源文件、类的增加和删除。
缺点
需要下次启动才修复。
3、阿里 AndFix
AndFix 采用 native hook 的方式,这套方案直接使用 dalvik_replaceMethod 替换 class 中方法的实现。由于它并没有整体替换 class, 而 field 在 class 中的相对地址在 class 加载时已确定,所以 AndFix 无法支持新增或者删除 filed 的情况(通过替换 init 与 clinit 只可以修改 field 的数值)。
原理
直接在 native 层进行方法的结构体信息对换,从而实现方法的新旧替换。
优点
补丁实时生效,不需要重新启动。
缺点
存在稳定及兼容性问题。ArtMethod 的结构基本参考 Google 开源的代码,各大厂商的 ROM 都可能有所改动,可能导致结构不一致,修复失败。
无法增加变量及类,只能修复方法级别的 Bug,无法做到新功能的发布。
4、FinClip 小程序容器热更新方案
虽说 h5 与小程序均能帮助 Hybrid 应用实现热更新,但鉴于小程序优于 h5 的性能,这里仅为大家介绍基于小程序容器的热更新方案。
FinClip是近几年大热的小程序容器技术,App 通过连接后台,从后台拉取小程序包,通过小程序容器运行,可以帮助「Native+小程序」混合开发应用实现热更新
原理:
实现了小程序的容器,由逻辑层负责与 SDK 交互,渲染层负责页面的渲染,同时由 SDK 提供路由界面跳转以及其他原生功能
SDK 通过运行时检查小程序的更新,动态进行小程序包的下载,实现功能的热更新
优点:
非侵入式的代码,对 apk 体积影响不大。
可扩展性高,由小程序接管业务逻辑,可以扩展任意功能
缺点:
只对 app 中的小程序页面有效,对原生模块无能为力。
FinClip 目前的产品迭代非常快,官方在不断优化产品、推出优惠。目前也正在举办有奖调研活动,对 FinClip 有兴趣的朋友不妨去参加一下,认真填写问卷的官方会发专属盲盒抽奖链接,中奖率贼高!手动指引:https://wj.qq.com/s2/10529758/2c72/
评论