安卓开发热修复技术原理及选型

转载  :  https://www.jianshu.com/p/b9ed58405ded

到我写这篇博文为止,现行的热修复技术主要有四种:美团的Robust、qq空间的Nuwa,微信的Tinker,阿里百川HotFix,但是更确切的说应该是有三种,Tinker和HotFix,因为Tinker是基于Nuwa的,原理一样,是它的进化版,我们到Github(https://github.com/jasonross/Nuwa )上可以看到,它已经一年没有更新了。

美团的Robust(Github链接官方文档),虽然最近都在更新,但是还不够完善,无法更新so\res等文件,没有形成系统的使用文档以及补丁包的管理,使用起来非常麻烦,所以在这里我们将分别讨论微信Tinker和阿里百川HotFix的原理及技术选型。

原理

一、Tinker

Tinker(官网链接) 是一个开源项目(Github链接),讲到Tinker的原理我们要先说说Nuwa的原理,Nuwa实现热修复的方案基于Android的dex分包基础上,dex分包是为了解决方法数达到64K天花板问题,简单来说就是将一个dex文件拆分成多个dex文件,在应用启动时其中一个作为主dex进行加载,应用启动后将会逐个加载其他dex,多个dex文件会排列成一个有序的数组,Dalvik虚拟机加载类的过程中,会顺序遍历这些dex文件,在每个dex文件中查找对应得类,如果找到就返回,没有找到就继续在下一个dex文件中查找。因此,理论上,如果多个dex文件中存在相同的类,那么排在数组前面的dex文件中的类将会被优选选择。因此,Numa实现热修复是将修复后的代码所在的dex插入到dex数组的最前面使达到新类替换旧类的目的,读者如果想深入了解可以看看这篇关于安卓加载类的过程的博文:https://juejin.im/entry/57c3a2a3c4c9710061927b6c , 原理如下图所示:

Nuwa实现原理.png

但是这种方案有一个缺点,由于新增加了dex,如果修复的类到了一定数量就会影响启动性能特备是再ART模式下更容易导致补丁包异常大,针对这个不足,微信提出了Tinker方案,原理如下:

图片.png

图片.png

二、阿里百川HoxFix(Sophix)

官网链接
阿里的热修复技术经历了Dexposed --->AndFix --> HoxFix 1.x --> HoxFix2.0.1(Sophix)的演化,
从最初的只支持方法修复到现在可以实现全修复,并且支持所有安卓系统版本,稳定性和兼容性、安全性都得到了大的提升,由于最新的Sophix没有开源,我们只能从它的前身AndFix(Github链接)去大概看看它的实现原理。AndFix只能修复方法,其参考了Hook的思想,跟Dexposed 相比做到了更好的系统兼容性。

AndFix修复方法的原理.png

对于实现方法的替换,需要在Native层操作,经过三个步骤,实现过程如下图所示:

图片.png

阿里Hotfix2.X 类修复方案

Hotfix2.X在热修复过程中是不侵入打包过程的,而是通过补丁工具生成补丁。由于热部署Andfix修复正在运行的方法有Crash的风险, 所以补丁工具提供参数由业务方来决定是否尝试走热部署;如果用户Patch的方法没有被高频调用同时又有实时生效的需求,那么可以优先选择走热部署方案;但这并非绝对,当代码变更导致热部署不支持时,还是会转向冷部署。

热部署

热部署不用重启应用就能够看到效果,就是AndFix支持的代码变更,此时走优化后的AndFix方案,也就是Hotfix1.X方案。

冷部署

冷部署需要重启应用才能够看到效果,就是AndFix不支持的代码变更。冷部署针对Davilk和Art分别做了不同的处理。

阿里Hotfix2.X SO文件修复方案

Davilk和ART下SO文件加载的方式不一样,导致了需要区分Art和Davilk做不同的处理:

ART下预Load原来的SO文件,再加载补丁SO文件;

Davilk下预Load补丁SO文件,再加载原来的SO文件。

这里的关键是:综合机型支持的Abis和补丁包中的Abis共同决定补丁SO的新LibPath。这两种加载方式都需要对加载两次SO文件,势必会增加一次本地内存的消耗,因此为了达到更好的性能,在Hotfix2.X中提供了下面两个接口替换掉系统加载SO文件的接口:

SOPatchManager.load(String libPath) 代替     System.load(String pathName)

SOPatchManager.loadLibrary(String libName)代替     System.loadLibrary(String libName)

阿里Hotfix2.X 资源文件修复方案

在资源文件中,资源ID编码于Resources.arsc文件中,排布紧密,并按照排布顺序进行自动编号;RES目录保存所有带ID的资源文件。布局文件为二进制形式的XML文件,XML以资源ID的方式引用其他资源;Assets目录存放所有原始文件,不带ID;Aapt进行资源的构造,包括自动分配资源ID与R文件的生成,默认情况下,每次编译不保证和之前包中的ID一致。

目前市面上普遍采用的三种资源修复方案:

1、差量合成完整的资源包,运行时完整加载资源;这种方案的缺点是:合成资源占用时间和内存,容易引起卡顿。
2、 修改aapt,对以后可能新增的资源提前留空,运行时Patch包中新增资源ID对应留出的位置;该方案的缺点是:需改变打包流程,修改代码并编译替换SDK中的Aapt;打包侵入太强,且留空占用一定磁盘空间。留空多少是预先定好的,无法改变。
3、插件化,组件化资源;这种方式的缺点是:资源需要划分模块,提前规划。

百川资源文件修复方案直接基于新旧两个APK来构造补丁包,不需要改造AAPT,对编译过程无要求;同时,精确比较各个资源ID的使用情况,最大程度利用原先基线包资源,补丁包中只包含新增和修改的资源;在运行时无需合成操作,快速应用生效,不影响性能

两种热修复技术对比(2017年3月29日为止最新)

项目阿里Sophix微信Thinker
类替换yesyes
so替换yesyes
资源替换yesyes
全平台支持yesyes
补丁包大小较小较小
即时生效yes(增删方法采用冷启动)no (重启生效)
性能损耗较小
侵入式打包无侵入式打包依赖侵入式打包
可视化打补丁包yesno
接入复杂度简单相对复杂
安全性加密传输及签名校验 、采用https请求未知
应用加固支持(用未加固的apk打补丁包)未知
费用免费日请求量<1W免费,大于1W按级别收取不同费用

目前官网公布的使用Sophix 的安卓应用,如下图所示:

图片.png

使用Tinker的应用目前只知道有微信,至于有没有其它产品,由于官方没有公布,暂时不知道。

总结

个人对比:
1、对bug修复及时,大部分bug不需要重新启动就可以立即看到效果;
2、接入的步骤比Tinker简单,降低了学习成本;
3、比Tinker更低的性能损耗;
4、最重要的:免费,以后会不会收费就不知道了;
5、Thinker收费,意味着更好的服务,更稳定的性能;
6、目前截止到Sophix2.0.9版本为止,对res下的文件bug修复易导致崩溃;
基于以上几点,我建议大家选择用Sophix 进行热更新;



作者:android开发经验总结
链接:https://www.jianshu.com/p/b9ed58405ded
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值