关于Android热修复的几种解决方案

文中引用到的一些博客:
http://www.jianshu.com/p/0a31d145cad2

https://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=400118620&idx=1&sn=b4fdd5055731290eef12ad0d17f39d4a

阿里推出方案的同时还出了本热修复的书链接放这里,推荐!
http://download.csdn.net/download/xlitol/9892768?spm=5176.doc53240.2.28.WgTrVf

一、Dexposed(@Deprecated)
项目地址:https://github.com/alibaba/dexposed

Dexposed是一个阿里巴巴手机淘宝基于Xposed进行的改进,产生了针对Android Dalvik 虚拟机运行时的Java Method Hook 技术--Dexposed。

在native层中先找到要修复的Java函数对应的Method对象,修改它变为native方法,把它的nativeFunc指向hookedMethodCallback。这样对这个java函数的调用就转为调用hookedMethodCallback这个native函数了,然后再用这个native函数回调java层自己实现的统一接口来处理。这个统一接口是XC_MethodReplacement类,它主要有beforeHookedMethod、afterHookedMethod和replaceHookedMethod等几个方法,前两个在执行原java函数前后做一些事,replaceHookedMethod则是替换原java方法。

但这个方案由于对底层Dalvik结构的过于依赖,最终无法兼容Android 5.0以后的ART虚拟机,所以现在也没什么卵用。

关于Dalvik和ART的区别:http://www.jianshu.com/p/58f817d176b7
贴俩篇详细hook的过程分析:

http://blog.csdn.net/yueqian_scut/article/details/50939034

http://blog.csdn.net/yueqian_scut/article/details/50939034

二、Andfix
项目地址:https://github.com/alibaba/AndFix

之前的博客有对其使用的介绍
http://blog.csdn.net/wy12345432452/article/details/77008963

Andfix 是支付宝提出的一种底层结构替换的方案,也达到了运行时即时生效的效果,并且重要的是,做到了Dalvik和ART环境的全版本兼容。

实现原理:
AndFix的原理就是方法的替换,把有bug的方法替换成补丁文件中的方法。

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

总结该方案的优缺点:
优点:

1.BUG修复的即时性

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

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

不足:

1.不支持新增字段,以及修改方法,也不支持对资源的替换。

2.由于厂商的自定义ROM,对少数机型暂不支持。兼容性差。

(每一个java方法在art种都对应一个ArtMethod, ArtMethod记录了这个java方法的所有信息,包括所属类,访问权限、代码执行地址。
通过evn->FromReflectedMethod,可以由Method对象得到这个方法对应的ArtMethod的真正其实地址,然后就可以把它强转为ArtMethod指针,从而对其所有的成员进行修改。这样就全部替换完之后就完成了热修复逻辑。以后调用这个方法时就会直接走到新方法的实现中了。
然而由于andfix里面的ArtMethod的结构体遵照android虚拟机art源码里面的ArtMethod构建的,各个手机厂商对这个ArtMethod结构体进行修改就会导致喝原来开源代码里面的结构不一致,那么在这个修改过的设备上,替换机制就会出问题,无法正常执行热修复逻辑。)

详细的源码分析:
http://blog.csdn.net/qxs965266509/article/details/49816007

三、阿里百川Hotfix(@Deprecated)
阿里百川Hotfix其实是阿里手机淘宝根据对Andfix的使用,对相关业务解偶后推出的,所以Andfix的缺点它也有。而且阿里已经在此基础上推出了更好的替代方案Sophix。所以这个这个以后基本上用不上了。

四、阿里Sophix
这个是阿里最新的一个解决方案,下面这个是官网。
https://www.aliyun.com/product/hotfix

这个是挂在github上的Demo。
https://github.com/aliyun/alicloud-android-demo/tree/master/hotfix_android_demo?spm=5176.doc53241.2.1.B9j904

阿里推出这个方案的同时出了本关于热修复的书,不止介绍了这个项目,而且介绍了很多热修复的原理,和在探索热修复时的一些思考,觉得还是值得好好看下的,地址在这里:
http://download.csdn.net/download/xlitol/9892768?spm=5176.doc53240.2.28.WgTrVf

下面是阿里系的热修复方案的对比。

从上图来看Sophix 应该是阿里系现在最好的了,相比其他的方案:

优点:

每个厂商的官网都不例外的说自己的方案怎么怎么好,下面摘自官网的介绍,根据我的试用进行了标注。

总体来说最大的优势在于:

1、补丁即时生效,不需要应用重启;(这个听着好像很爽,其实好多时候还是都要冷启动才能生效,如果是资源文件要好几次下面是官网的图)

2、补丁包同样采用差量技术,生成的PATCH体积小;
3、对应用无侵入,几乎无性能损耗;
4、傻瓜式接入。(这个确实接入很简单,后台使用也简单,生成补丁的工具也是图形化的)

缺点:
1、这个不开源,只能用阿里的后台,如果你想发布在自己的后台那就不能用了。

五、QQ空间超级补丁技术
参考博文:
https://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=400118620&idx=1&sn=b4fdd5055731290eef12ad0d17f39d4a

超级补丁技术基于DEX分包方案,使用了多DEX加载的原理,大致的过程就是:把BUG方法修复以后,放到一个单独的DEX里,插入到dexElements数组的最前面,让虚拟机去加载修复完后的方法。

当patch.dex中包含Target.class时就会优先加载,在后续的DEX中遇到Target.class的话就会直接返回而不去加载,这样就达到了修复的目的。

六、Tinker
项目官网:http://www.tinkerpatch.com/

Tinker 是开源项目Github的地址:https://github.com/Tencent/tinker

参考:http://www.cnblogs.com/yyangblog/p/6268818.html

微信针对QQ空间超级补丁技术的不足提出了一个提供DEX差量包,整体替换DEX的方案。主要的原理是与QQ空间超级补丁技术基本相同,区别在于不再将patch.dex增加到elements数组中,而是差量的方式给出patch.dex,然后将patch.dex与应用的classes.dex合并,然后整体替换掉旧的DEX,达到修复的目的。

整体的流程是:

从流程图来看,同样可以很明显的找到这种方式的特点:

优势:

1.合成整包,不用在构造函数插入代码,防止verify,verify和opt在编译期间就已经完成,不会在运行期间进行。

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

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

不足:

1.与超级补丁技术一样,不支持即时生效,必须通过重启应用的方式才能生效。

2.需要给应用开启新的进程才能进行合并,并且很容易因为内存消耗等原因合并失败。

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

七、Amigo
项目地址:https://github.com/eleme/Amigo

参考博文:http://blog.csdn.net/yangxi_pekin/article/details/52523872

八、Robust
Robust插件对每个产品代码的每个函数都在编译打包阶段自动的插入了一段代码,插入过程对业务开发是完全透明。在Application中通过DexClassLoader,将补丁class文件事先加载,然后之后会调用新的class以替换旧apk中的bug class文件,通过反射进行新代码的调用,以达到热修复目的。大致流程如下图

优点:
1、高兼容和适配性,由于是java代码层面的替换调用,基本不涉及各个版本的适配和虚拟机的适配。
缺点:
1、由于对包体中的文件进行了代码侵入,对运行效率、方法数、包体积都有影响,文件方法数变多,企业级应用可能会涉及到65535的问题。
2、项目不够成熟,文档不够健全。

猜你喜欢

转载自www.cnblogs.com/zhujiabin/p/9944784.html