一、背景
热修复技术其实已经出来很久了,目前市面上只要是能上得了台面的App基本都加入这项强大技术来实现bug修复功能。但是我相信依旧有很多做Android开发的朋友和我一样都还是停留在知道有这项技术,但是不知道怎么用这项技术,更加不用说它的实现原理了。我觉得出现这样一个现象的原因有两个,一个是现实中没有项目去驱动我们做这件事,二个就是很多人都讨厌甚至惧怕接触新的技术,毕竟头发比较宝贵嘛。但是这也就是我们为什么薪水同样没有别人高的原因,学无止境!
今天我们就一点点的记录下我们手撸热修复框架的学习过程。其实目前市场上已经有很多比较牛逼的热更新框架了,都是由国内几家技术龙头企业里面的大牛们开发的,且很多都是开源的。按理我们只要直接使用他们的框架就好了。但是经过实践我发现,很多时候如果你一点都不懂整个热修复的原理的话即使你接入别人写好的框架也同样会碰到一堆的问题,甚至是接入失败,这个时候我们基本就手足无措了,不知道该怎么解决,或者百度到解决方法后,并不知道为什么要这样解决,下次遇到还是不会的窘境。这就迫使我们自己至少要懂一点热更新的原理。
整个系列我们会分成三部分来描述:
二、目前热门的热更新框架
首先我们通过一张表来看一下目前使用的比较火的开源框架有哪些,以及他们之间的区别。
这其中比较出名的有腾讯Tinker、阿里的AndFix、美团的Robust以及QQ空间的QZone的超级补丁方案。
(1)AndFix
即时生效不需要重启App,且不会替换任何的类或者so,是通过native动态替换java层的方法,在native层hook java层的代码来实现的。简单点来说就是修改方法的指针引用,即将有bug的方法指针重定向到一个已经修复bug的方法上去。不支持资源文件和so文件的修复。
(2)Robust
美团热修复框架同样即时生效不需要重启App,且不需要替换类。而是对每个函数在编译打包阶段自动的插入了一段代码(这里面涉及到注解和插桩技术)。类似于代理,将方法执行的代码重定向到其他方法中。
(3)Tinker
腾讯的Tinker是通过计算对比指定的Base Apk中的dex与修改后的Apk中的dex的区别,通过差分算法(dexdiff)获取到补丁包dex。运行时将Base Apk中的dex与补丁包dex进行合成,重启后加载全新的合成后的dex文件。这里就和上面两个框架有所不同了,它的修复原理就是通过ClassLoader去替换有bug的类了。同时它还支持so的修复以及资源文件的修复。需要重启App才能够生效。
(4)Qzone
QQ空间基于的是dex分包方案(multidex)。把BUG方法修复以后,放到一个单独的dex补丁文件中,让程序运行期间加载dex补丁,执行修复后的方法。如何做到这一点呢?在Android中所有我们运行期间需要的类都是由ClassLoader(类加载器)进行加载。因此让ClassLoader加载全新的类替换掉出现Bug的类即可完成热修复。ClassLoader如何在运行时去替换类呢?这个其实在前面的类加载章节有讲过。有兴趣的朋友可以去了解下,这里就不再重述了。Qzone同样需要重启App生效,且支持资源文件修复,但是不支持so文件修复。