热更新

热更新调研
ps:本文是参考网上的资源而写的,参考链接如下:
Android热修复技术原理详解
Android热更新技术总结
Android热修复技术总结
阿里最新热修复Sophix与QQ超级补丁和Tinker的实现与总结

  1. 现有解决方案:
    腾讯系:Tinker (冷启动修复)、Qzone超级补丁(冷启动修复)、QFix(冷启动修复)
    阿里系:Andfix (native hook 实时修复)、Sophix 新一代(实时修复+冷启动修复)、Xposed (不支持Art虚拟机,已废弃) Dexposed(思想来源于Xposed)
    美团:Robust 每个函数插入额外逻辑(实时修复
    饿了吗:Amigo(冷启动修复)
    大众点评:Nuwa(参考Qzone实现开源,冷启动修复)
    百度金融: RocooFix:冷启动修复)
    美丽说蘑菇街:Aceso(实时修复
    360:RePlugin
    滴滴出行: VirtualAPK
    下图是现有各大公司主要的热修复解决方案

    热更新_第1张图片
    热修复现状.png

  2. 热修复开发流程:
    上线--》安装--》发现bug--》紧急修复--》打出补丁,推送用户--》自动拉取补丁修复
    修复主要包含以下三方面:代码修复、资源修复、so库修复。

  3. 使用原理:追根溯源热更新实现的基本原理,可以划分为以Tinker为代表的multidex类加载法和以阿里Andfix为代表的底层替换法,而阿里Sophix为了提高热修复的成功率同时采用了上述两种方案,并在兼容性上进行了一定的优化。

根据实现原理也可以把各家公司的解决方案按照下图来分类:


热更新_第2张图片
热修复按使用原理分类.png

或者更详细技术原理,可以更细化分类如下:


热更新_第3张图片
详细分类.png
  1. 技术原理与特点:

Tinker : Multidex类加载法:
在android5.0之前,每个android应用只含有一个dex文件,dex的方法数量被限制在了65535之内,导致apk引入大量第三方sdk后方法数量超过限制无法编译通过。为了解决这个问题,Google推出多dex文件的解决方案multidex,一个apk可以包含多个dex文件。通过Multidex.install(this)完成dex文件的加载。

Tinker方案参考multidex实现原理,在编译时通过新旧两个Dex生成差异patch.dex。在运行时,将差异patch.dex重新和原始安装包的旧Dex合并还原为新的Dex。这个过程可能比较耗费时间与内存,所以tinker单独放在一个后台进程:patch中处理。为了补丁包尽量的小,微信自研了DexDiff算法,它深度利用Dex的格式来减少差异的大小。

优点:
支持动态下发代码
支持替换So库以及资源

缺点:
由于采用ClassLoader机制,所以需要app重启。由于类加载实现原理涉及dex文件的重新解压缩合并等处理,消耗内存大,耗时长,在系统低内存时容易导致热更新失败,腾讯测试成功率大概为95%。

Andfix : 底层替换方案
底层替换是在已经加载了的类中直接在native层用新的方法替换掉原有的出现bug的方法。与Dexposed一样都基于开源框架Xposed实现,是一种AOP解决方案

热更新_第4张图片
底层替换.png

优点是: 即时生效,支持dalvik和art(AndFix supports Android version from 2.3 to 7.0, both ARM and X86 architecture, both Dalvik and ART runtime, both 32bit and 64bit.)
与Dexposed框架相比, AndFix框架更加轻便好用,在进行热修复的过程中更加方便了。

缺点是:面临稳定性与兼容性问题
AndFix不支持新增方法,新增类,新增field等

Sophix :整体替换方式

热更新_第5张图片
Sophix.png

由于底层替换原理只支持方法替换,不支持方法的增加和减少,成员字段的增加和减少,所以我们需要知道哪些修改会导致方法,字段的改变,从而导致底层替换热部署失效。Sophix改变了一下思路,采用整体替换方法结构,忽略底层实现,从而解决兼容稳定性问题。

Dalvik下采用阿里自研的全量dex方案:不是考虑把补丁包的dex插到所有dex前面(dex插桩),而是想办法在原理的dex中删除(只是删除了类的定义)补丁dex中存在的类,这样让系统查找类的时候在原来的dex中找不到,那么只有补丁中的dex加载到系统中,系统自然就会从补丁包中找到对应的类。

优点是实现热部署,修改及时生效,支持代码修复、资源修复、so库修复。

美团Robust :Instant Run 热插拔原理
Robust插件对每个产品代码的每个函数都在编译打包阶段自动的插入了一段代码,插入过程对业务开发是完全透明的。
编译打包阶段自动为每个class都增加了一个类型为ChangeQuickRedirect的静态成员,而在每个方法前都插入了使用changeQuickRedirect相关的逻辑,当 changeQuickRedirect不为null时,可能会执行到accessDispatch从而替换掉之前老的逻辑,达到fix的目的。

热更新_第6张图片
Install Run热插拔原理.png

优点:
几乎不会影响性能(方法调用,冷启动)
支持Android2.3-8.x版本
高兼容性(Robust只是在正常的使用DexClassLoader)、高稳定性,修复成功率高达99.9%
补丁实时生效,不需要重新启动
支持方法级别的修复,包括静态方法
支持增加方法和类
支持ProGuard的混淆、内联、优化等操作
缺点:
代码是侵入式的,会在原有的类中加入相关代码
so和资源的替换暂时不支持
会增大apk的体积,平均一个函数会比原来增加17.47个字节,10万个函数会增加1.67M。
会增加少量方法数,使用了Robust插件后,原来能被ProGuard内联的函数不能被内联了

  1. 各家公司产品对比:
热更新_第7张图片
Sophix对比.png
热更新_第8张图片
Tinker对比.png

热更新_第9张图片
Qzone对比.png
  1. 总结:如果不考虑增大apk的体积,只是简单的修复代码,不修复so和资源,选择美团的 Robust是最稳定的,否则的话选择Tinker是一个不错的方案。目前腾讯的 Tinker基本可以满足app的热更新需求,但随着app用户规模不断增大,业务需求日益复杂,可考虑阿里的sophix商业方案,sophix同时应用类加载和底层替换两种方案,具有底层替换的修改及时性,和类加载方案的兼容性等优点。虽然阿里Sophix横空出世,但是它不开源,而且商业收费(用户量大的话会收费),所以一般不是很赚钱的app选择收费的可能就很小了,不过它确实各方面都做了大量的优化。

你可能感兴趣的:(热更新)