几种主流热修复方案分析

热修复是在Android上一种越来越流行的技术,需要对底层原理有比较清晰的了解。今天看下几种主流热修复方案分析:


  • 为什么使用热修复

  • 使用热修复后

  • 热修复的流派

  • 主流的热修复方案分析

  • 对比分析

为什么使用热修复

  • 重新发布版本代价太大

  • 用户下载安装成本太高

  • BUG修复不及时,用户体验太差

使用热修复后

  • 无需重新发版,实时高效热修复

  • 用户无感知修复,无需下载新的应用,代价小

  • 修复成功率高,把损失降到最低

热修复流派

1、底层替换方案
底层替换方案限制颇多,但时效性最好,加载轻快,立即见效。
代表:支付宝的Andfix
2、类加载方案
类加载方案时效性差,需要重新冷启动才能见效,但修复范围广,限制少。
百度实现的HotFix、QQ空间补丁技术、Qfix方案、微信的Tinker方案
3、融合方案
两种方案的结合,优势互补。
Sophix

Andfix

AndFix的思想是直接更改修复的方法,就是找到这个类中需要修复的函数然后调用replaceMethod方法。在Native层使用指针替换的方式替换bug方法,以达到修复bug的目的。

优点:

  • BUG修复的即时性

  • 补丁包同样采用差量技术,生成的PATCH体积小

  • 对应用无侵入,几乎无性能损耗

局限性:

  • 只能基于方法修复,而且对平台的兼容性不佳,

  • 不支持新增字段,以及修改

    方法,也不支持对资源的替换。

QQ空间超级补丁技术

超级补丁技术原理是基于Android Dex分包方案的,而Dex分包方案的关键就是Android的ClassLoader体系。
关键点:DexClassLoader可以用来执行没有安装的程序代码

除了类加载问题之外还存在CLASS_ISPREVERIFIED标记的问题:
只要在static方法,构造方法,private方法,override方法中直接引用了其他dex中的类,那么这个类就不会被打上CLASS_ISPREVERIFIED标记。

解决方案:在所有类的构造函数中插入这行代码 System.out.println(AntilazyLoad.class);

超级补丁技术原理是基于Android Dex分包方案的,而Dex分包方案的关键就是Android的ClassLoader体系。把多个dex文件塞入到app的classloader之中android加载的时候,如果有多个dex文件中有相同的类,就会加载前面的类,原理就是把有问题的类替换掉,把需要的类放到最前面,达到热补的目的。

优势:

  • 没有合成整包(和微信Tinker比起来),产物比较小,比较灵活

  • 可以实现类替换,兼容性高

不足:

  • 不支持即时生效,必须通过重启才能生效。

  • 在ART模式下,如果类修改了结构,就会出现内存错乱的问题。为了解决这个问题,就必须把所有相关的调用类、父类子类等等全部加载到patch.dex中,导致补丁包异常的大,进一步增加应用启动加载的时候,耗时更加严重。

Tinker

  • Tinker也是Dex加载原理, 不同是,Tinker 下发新旧DEX的差异包,优化了DexDiff算法实现dexPatch体积更小。然后将差异包和旧包合成新dex之后进行dex的全量替换,避免了QQ补丁中的插桩操作。

  • 全量合成新dex,消除重复class重复带来的冲突

优势:

  • 合成整包,不用在构造函数插入代码。

  • 性能提高。兼容性和稳定性比较高。

  • 开发者透明,不需要对包进行额外处理。

不足:

  • 不支持即时生效,必须通过重启应用的方式才能生效。

  • 开启新的进程才能进行合并,并且很容易因为内存消耗等原因合并失败。

  • 合并时占用额外磁盘空间,对于多DEX的应用来说,如果修改了多个DEX文件,就需要下发多个patch.dex与对应的classes.dex进行合并操作时这种情况会更严重,因此合并过程的失败率也会更高。

Sophix

Sophix的代码修复同时涵盖底层替换方案和类加载方案。在补丁生成阶段,补丁工具会根据实际代码变动情况进行自动选择,针对小修改,在底层替换方案限制范围内的,就直接采用底层替换修复方案,而对于代码修改超出底层替换限制的,会使用类加载替换,此时及时性没那么好。
另外,运行时阶段,Sophix还会再判断所运行的机型是否支持热修复,这样即使补丁支持热修复,但由于机型底层虚拟机构造不支持,还是会走类加载修复,从而达到最好的兼容性。

Sophix资源修复方案,优越性超过了Google官方的Instant Run方案。整个资源替换的方案优势在于:

  1. 不修改AssetManager的引用处,替换更快更完全。(对比Instanat Run以及所有copycat的实现)

  2. 不必下发完整包,补丁包中只包含有变动的资源。(对比Instanat Run、Amigo等方式的实现)

  3. 不需要在运行时合成完整包。不占用运行时计算和内存资源。(对比Tinker的实现)

So修复:类似类修复反射注入方式。把补丁so库的路径插入到nativeLibraryDirectories数组的最前面,就能够达到加载so库的时候是补丁so库,而不是原来so库的目录,从而达到修复的目的。采用这种方案,完全由Sophix在启动期间反射注入patch中的so库

优点:
  1、Sophix集成简单,不需要配置繁琐的各种参数。
  2、Sophix支持即时生效(事实上我第一次运行first版本后,直接就弹出了toast,而此时后台数据显示设备加载成功数为1,设备推送成功数为0)。
  3、Sophix支持run instant,而tinker不支持。编译中不支持run instant,速度大大降低!
  4、Sophix的补丁是基于阿里自身的SophixPatchTool打包生成,不是在AS中生成的,有种解耦的感觉,而且不需要备份太多的版本。

缺点:
  处于公测阶段,可能面临收费

热修复框架对比

参考资料:

https://github.com/alibaba/AndFix
https://github.com/dodola/HotFix
https://github.com/Tencent/tinker
https://github.com/jasonross/Nuwa
https://github.com/bunnyblue/DroidFix
http://blog.csdn.net/u013795543/article/details/73250166

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值