手记

Android关于热修复

热修复:

热修复(也称热补丁、热修复补丁,英语:hotfix)是一种包含信息的独立的累积更新包,通常表现为一个或多个文件。这被用来解决软件产品的问题(例如一个程序错误)。——维基百科

目前的热修复框架:

1.阿里Dexposed

2.阿里AndFix -- native解决方案

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

4.美团Robust -- Instant Run 热插拔

阿里Dexposed -- native解决方案
原理:

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

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

基于开源框架Xposed实现,是一种AOP解决方案

只Hook App本身的进程,不需要Root权限

优点:

即时生效

不需要任何编译器的插桩或者代码改写,对正常运行不引入任何性能开销。这是AspectJ之类的框架没法比拟的优势;

对所改写方法的性能开销也极低(微秒级),基本可以忽略不计;

从工程的角度来看,热补丁仅仅是牛刀小试,它真正的威力在于『线上调试』;

基于Xposed原理实现的AOP不仅可以hook自己的代码,还可以hook同进程的Android SDK代码。

缺点

Dalvik上近乎完美,不支持ART(需要另外的实现方式),所以5.0以上不能用了;
最大挑战在于稳定性与兼容性,而且native异常排查难度更高;
由于无法增加变量与类等限制,无法做到功能发布级别;

Dexposed源码:https://github.com/alibaba/dexposed

Xposed源码:https://github.com/rovo89/Xposed

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源码:https://github.com/alibaba/AndFix

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

原理是Hook了ClassLoader.pathList.dexElements[]。因为ClassLoader的findClass是通过遍历dexElements[]中的dex来寻找类的。当然为了支持4.x的机型,需要打包的时候进行插桩。

越靠前的Dex优先被系统使用,基于类级别的修复

优点:

不需要考虑对dalvik虚拟机和art虚拟机做适配

代码是非侵入式的,对apk体积影响不大

缺点:

需要下次启动才会生效

最大挑战在于性能,即Dalvik平台存在插桩导致的性能损耗,Art平台由于地址偏移问题导致补丁包可能过大的问题

虚拟机在安装期间为类打上CLASS_ISPREVERIFIED标志是为了提高性能的,我们强制防止类被打上标志是否会影响性能?这里我们会做一下更加详细的性能测试.但是在大项目中拆分dex的问题已经比较严重,很多类都没有被打上这个标志。

Nuwa源码:https://github.com/jasonross/Nuwa
HotFix源码:https://github.com/dodola/HotFix
DroidFix源码:https://github.com/bunnyblue/DroidFix

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内联的函数不能被内联了



作者:行者_zm
链接:https://www.jianshu.com/p/be0796c90333


0人推荐
随时随地看视频
慕课网APP