抱歉,你查看的文章不存在

几种主流热修复方案分析

热修复是在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

原文发布于微信公众号 - 何俊林(DriodDeveloper)

原文发表时间:2018-03-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

码农突围

0 篇文章93 人订阅

相关文章

来自专栏安恒网络空间安全讲武堂

​writeup | 强网杯—Share your mind

0x01 分析题目 拿到题目后,首先先分析一下题目,发现有注册和登录,尝试登录成功后,发现如下几个页面 Overview // 显示当前自己所有发帖 Write...

36960
来自专栏美团技术团队

磁盘I/O那些事

背景 计算机硬件性能在过去十年间的发展普遍遵循摩尔定律,通用计算机的CPU主频早已超过3GHz,内存也进入了普及DDR4的时代。然而传统硬盘虽然在存储容量上增长...

1.3K100
来自专栏微信终端开发团队的专栏

Hello Bonjour!

Hello Bonjour! 一开始用Bonjour,我是拒绝的。 让我们以一个问题开头:如何能在本地网络找到自己想要的硬件设备及相应服务,并连接? 在这个以I...

286100
来自专栏文武兼修ing——机器学习与IC设计

AXI学习笔记-11.AXI总线结构2.AXI接口时序3.数据结构4.传输特性

握手信号包括VALID和READY信号,传输行为仅在VALID和READY同时有效时发生。其中:

60030
来自专栏杨建荣的学习笔记

Oracle 12C打补丁的简单尝试(r10笔记第55天)

最近在服务器盘点的时候,发现测试环境还是值得整合一下,因为服务器资源老旧,整体配置不高,服务器资源使用率不高,业务要求不高,多个实例分散在多台服务器上,要考虑灾...

39980
来自专栏张善友的专栏

MongoDB核心贡献者:不是MongoDB不行,而是你不懂!

近期MongoDB在Hack News上是频繁中枪。许多人更是声称恨上了MongoDB,David mytton就在他的博客中揭露了MongoDB许多现存问题。...

256100
来自专栏腾讯移动品质中心TMQ的专栏

【浅谈Chromium中的设计模式(一)】——Chromium中模块分层和进程模型

“EP”(中文:工程生产力)是目前项目中提升研发能力的一个很重要的衡量指标。笔者重点学习了Chromium产品是如何从代码和设计层面来保证快速高效的工程生产力。...

53880
来自专栏Golang语言社区

大型服务端开发的反模式技巧

1. 用线程池执行异步任务 ? 为了减少阻塞时间,加快响应速度,把无需返回结果的操作变成异步任务,用线程池来执行,这是提高性能的一种手段。 你可能要惊讶了,这么...

36650
来自专栏影子

给Ionic写一个cordova(PhoneGap)插件

500100
来自专栏我的安全视界观

[一起玩蛇】Python代码审计中的器II

32470

扫码关注云+社区

领取腾讯云代金券