Android热修复技术原理详解(最新最全版本)

本文框架

  • 什么是热修复?
  • 热修复框架分类
  • 技术原理及特色
  • Tinker框架解析
  • 各框架对比图
  • 总结

  经过阅读本文,你会对热修复技术有更深的认知,本文会列出各种框架的优缺点以及技术原理,文章末尾简单描述一下Tinker的框架结构。html

1、什么是热修复?

正常开发流程

热修复开发流程

热修复优点

修复什么?

2、热修复框架分类

现状:百花齐放百家争鸣

简单分类

更合理的分类

3、技术原理及特色

3.1 阿里Dexposed -- native解决方案

原理:

  • 直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能

  他的思想彻底来源于Xposed框架,完美诠释了AOP编程,这里用到最核心的知识点就是在native层获取到指定方法的结构体,而后改变他的nativeFunc字段值,而这个值就是能够指定这个方法对应的native函数指针,因此先从Java层跳到native层,改变指定方法的nativeFunc值,而后在改变以后的函数中调用Java层的回调便可。实现了方法的拦截功能。android

  • 基于开源框架Xposed实现,是一种AOP解决方案
  • 只Hook App自己的进程,不须要Root权限

优势:

  • 即时生效
  • 不须要任何编译器的插桩或者代码改写,对正常运行不引入任何性能开销。这是AspectJ之类的框架无法比拟的优点;
  • 对所改写方法的性能开销也极低(微秒级),基本能够忽略不计;
  • 从工程的角度来看,热补丁仅仅是牛刀小试,它真正的威力在于『线上调试』;
  • 基于Xposed原理实现的AOP不只能够hook本身的代码,还能够hook同进程的Android SDK代码,这也就可让咱们有能力在App中填上Google本身挖的坑。

缺点:

  • Dalvik上近乎完美,不支持ART(须要另外的实现方式),因此5.0以上不能用了;
  • 最大挑战在于稳定性与兼容性,并且native异常排查难度更高;
  • 因为没法增长变量与类等限制,没法作到功能发布级别;

相关连接:

3.2 阿里AndFix -- native解决方案

原理:

  • 与Dexposed同样都基于开源框架Xposed实现,是一种AOP解决方案

优势:

  • 即时生效
  • 支持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等

AndFix(Dexpsed)框架不稳定的缘由(痛点)

相关连接:

3.3 QQ空间--Dex插桩方案(大众点评的Nuwa参考其实现并开源)

原理:

  • 原理是Hook了ClassLoader.pathList.dexElements[]。由于ClassLoader的findClass是经过遍历dexElements[]中的dex来寻找类的。固然为了支持4.x的机型,须要打包的时候进行插桩。
  • 越靠前的Dex优先被系统使用,基于类级别的修复

优势:

  • 不须要考虑对dalvik虚拟机和art虚拟机作适配
  • 代码是非侵入式的,对apk体积影响不大

缺点:

  • 须要下次启动才会生效
  • 最大挑战在于性能,即Dalvik平台存在插桩致使的性能损耗,Art平台因为地址偏移问题致使补丁包可能过大的问题
  • 虚拟机在安装期间为类打上CLASS_ISPREVERIFIED标志是为了提升性能的,咱们强制防止类被打上标志是否会影响性能?这里咱们会作一下更加详细的性能测试.可是在大项目中拆分dex的问题已经比较严重,不少类都没有被打上这个标志。

插桩方案性能上的痛点:

相关连接:

3.4 美团Robust -- Instant Run 热插拔原理

原理:

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

优势:

  • 几乎不会影响性能(方法调用,冷启动)
  • 支持Android2.3-8.x版本
  • 高兼容性(Robust只是在正常的使用DexClassLoader)、高稳定性,修复成功率高达99.9%
  • 补丁实时生效,不须要从新启动
  • 支持方法级别的修复,包括静态方法
  • 支持增长方法和类
  • 支持ProGuard的混淆、内联、优化等操做

缺点:

  • 代码是侵入式的,会在原有的类中加入相关代码
  • so和资源的替换暂时不支持
  • 会增大apk的体积,平均一个函数会比原来增长17.47个字节,10万个函数会增长1.67M。
  • 会增长少许方法数,使用了Robust插件后,原来能被ProGuard内联的函数不能被内联了

相关连接:

3.5 微信Tinker

原理:

  • 服务端作dex差量,将差量包下发到客户端,在ART模式的机型上本地跟原apk中的classes.dex作merge,merge成为一个新的merge.dex后将merge.dex插入pathClassLoader的dexElement,原理类同Q-Zone,为了实现差量包的最小化,Tinker自研了DexDiff/DexMerge算法。Tinker还支持资源和So包的更新,So补丁包使用BsDiff来生成,资源补丁包直接使用文件md5对比来生成,针对资源比较大的(默认大于100KB属于大文件)会使用BsDiff来对文件生成差量补丁。


优势:

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

缺点:

  • 不能即时生效,须要下次启动

Tinker已知问题:

  • Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件(1.9.0支持新增非export的Activity);
  • 因为Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
  • 在Android N上,补丁对应用启动时间有轻微的影响;
  • 不支持部分三星android-21机型,加载补丁时会主动抛出"TinkerRuntimeException:checkDexInstall failed";
  • 对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标。

Tinker性能痛点:

  • Dex合并内存消耗在vm head上,容易OOM,最后致使合并失败。
  • 若是自己app占用内存已经比较高,可能容易致使app本系统杀掉。

相关连接:

3.6 阿里Sophix

原理(双剑合璧):

优化Andfix(突破底层结构差别,解决稳定性问题):


Andfix底层ArtMethod结构时采用内部变量一一替换,却是这个各个厂商是会修改的,因此兼容性很差。git

Sophix改变了一下思路,采用总体替换方法结构,忽略底层实现,从而解决兼容稳定性问题。github

突破QQ和Tinker的缺陷


QQ和Tinker的缺陷算法

Sophix对dex的解决方案编程

  • Dalvik下采用阿里自研的全量dex方案:不是考虑把补丁包的dex插到全部dex前面(dex插桩),而是想办法在原理的dex中删除(只是删除了类的定义)补丁dex中存在的类,这样让系统查找类的时候在原来的dex中找不到,那么只有补丁中的dex加载到系统中,系统天然就会从补丁包中找到对应的类。
  • Art下本质上虚拟机以及支持多dex的加载,Sophix的作法仅仅是把补丁dex做为主dex(classes.dex)而已,至关于从新组织了全部的dex文件:把补丁包的dex更名为classes.dex,之前apk的全部dex依次改成classes2.dex、classes3.dex ... classesx.dex,以下图所示。

资源修复另辟蹊径


经常使用方案(Instant Run技术):这种方案的兼容问题在于替换AssetManager的地方微信

Sophix资源修复方案app

SO修复另辟蹊径


4、Tinker框架解析

  之因此只贴了Tinker的代码框架,是由于目前开源的方案中是最好的,固然除了Robust。框架

代码结构

修复流程

这里后续再补一个详细的源码分析,敬请期待函数

5、对比图(来自不一样的地方)

来自Tinker的对比

来自Sophix的对比

来自蘑菇街 Android 热修复探索之路

其余文章

浅谈Android热修复:

6、总结

  若是不考虑增大apk的体积,只是简单的修复代码,不修复so和资源,选择Robust是最稳定的,不然的话选择Tinker是一个不错的方案。虽然阿里Sophix横空出世,可是它不开源,并且商业收费,因此通常不是很赚钱的app选择收费的可能就很小了。不过它确实各方面都作了大量的优化,本文中的不少知识点也来源于阿里的《Android热修复技术原理.pdf》一书,本书值得一读,里面就是基于Sophix框架来编排的。

GitHub文章地址

相关文章
相关标签/搜索