三分钟的介绍
热修复技术,可以看做是Android平台发展成熟至一定阶段的必然产物。热修复无疑是这2年较火的新技术,是作为安卓工程师必学的技能之一。在热修复出现之前,一个已经上线的app中如果出现了bug,即使是一个非常小的bug,不及时更新的话有可能存在风险,若要及时更新就得将app重新打包发布到应用市场后,让用户再一次下载,这样就大大降低了用户体验,当热修复出现之后,这样的问题就不再是问题了。
国内大部分成熟的主流APP都拥有自己的热更新技术,像手淘、支付宝、微信、QQ、饿了么、美团等。
先来看一下对比图
热修复技术实现的原理(AndFix)
Andfix 是支付宝提出的一种底层结构替换的方案,也达到了运行时即时生效的效果,并且重要的是,做到了Dalvik和ART环境的全版本兼容。
AndFix的原理就是方法的替换,把有bug的方法替换成补丁文件中的方法。在Native动态替换Java层的方法,通过Native层hook Java层的代码
优点:
1.BUG修复的即时性
2.补丁包同样采用差量技术,生成的PATCH体积小
3.对应用无侵入,几乎无性能损耗
不足:
1.不支持新增字段,以及修改方法,也不支持对资源的替换。
2.由于厂商的自定义ROM,对少数机型暂不支持。兼容性差。
每个Java方法在art下面都对应的一个ArtMethod结构体,ArtMethod记录了这个Java方法的所有信息,包括所属类,访问权限、代码执行地址。通过evn->FromReflectedMethod,可以由Method对象得到这个方法对应的ArtMethod的真正地址,然后就可以把它强转为修复后的ArtMethod指针,从而对其所有的成员进行修改。这样就全部替换完之后就完成了热修复逻辑。以后调用这个方法时就会直接走到新方法的实现中了。 然而由于andfix里面的ArtMethod的结构体遵照android虚拟机art源码里面的ArtMethod构建的,各个手机厂商对这个ArtMethod结构体进行修改就会导致喝原来开源代码里面的结构不一致,那么在这个修改过的设备上,替换机制就会出问题,无法正常执行热修复逻辑。
热修复技术实现的原理(Hotfix)
阿里百川Hotfix其实是阿里手机淘宝根据对Andfix的使用,对相关业务解偶后推出的,所以Andfix的缺点它也有。而且阿里已经在此基础上推出了更好的替代方案Sophix。所以这个这个以后基本上用不上了。
热修复技术实现的原理(Sophix)
阿里百川Hotfix其实是阿里手机淘宝根据对Andfix的使用,对相关业务解偶后推出的,所以Andfix的缺点它也有。而且阿里已经在此基础上推出了更好的替代方案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
阿里推出这个方案的同时出了本关于热修复的书,不止介绍了这个项目,而且介绍了很多热修复的原理,和在探索热修复时的一些思考,觉得还是值得好好看下的,地址在这里:
深入探索Android热修复技术原理
热修复技术实现的原理(美团Robust)
Robust插件对每个产品代码的每个函数都在编译打包阶段自动的插入了一段代码,插入过程对业务开发是完全透明。在Application中通过DexClassLoader,将补丁class文件事先加载,然后之后会调用新的class以替换旧apk中的bug class文件,通过反射进行新代码的调用,以达到热修复目的。大致流程如下图
美团的官方地址:
https://tech.meituan.com/2016/09/14/android-robust.html
优点:
1、高兼容和适配性,由于是java代码层面的替换调用,基本不涉及各个版本的适配和虚拟机的适配。
缺点:
1、由于对包体中的文件进行了代码侵入,对运行效率、方法数、包体积都有影响,文件方法数变多,企业级应用可能会涉及到65535的问题。
2、项目不够成熟,文档不够健全。
热修复技术实现的原理(QQ空间)
QQ空间基于的是dex分包方案。把BUG方法修复以后,放到一个单独的dex补丁文件,让程序运行期间加载dex补丁,执行修复后的方法。如何做到这一点?
在Android中所有我们运行期间需要的类都是由ClassLoader(类加载器)进行加载。
因此让ClassLoader加载全新的类替换掉出现Bug的类即可完成热修复。
热修复技术实现的原理(Tinker)
重启生效、反射、类加载、DexDiff
项目官网:http://www.tinkerpatch.com/
Tinker 是开源项目Github的地址:https://github.com/Tencent/tinker
微信针对QQ空间超级补丁技术的不足提出了一个提供DEX差量包,整体替换DEX的方案。主要的原理是与QQ空间超级补丁技术基本相同,区别在于不再将patch.dex增加到elements数组中,而是差量的方式给出patch.dex,然后将patch.dex与应用的classes.dex合并,然后整体替换掉旧的DEX,达到修复的目的。(差分包,腾讯根据增量更新bspatch自己开发了一个dexdiff针对dex格式的,bsdiff算法计算差分与格式无关,基于二进制的,产物不稳定)跟QQ空间的区别主要在于补丁包的生成不一样,后面拿到补丁包后是一样的。