Android 热修复 技术浅析

2017-02-26  本文已影响0人  feifei_fly

一、Android 中的两大流派:

1、Native Hook 流派:改写 方法:淘宝的Dexposed,支付宝的AndFix 、Rebust、instantRun ?

Dexposed只只吃Android 5.0之下,不支持全平台。

2、dex hack 流派:QQ超级补丁,Tinker 。

二、方案分析

http://www.chinaz.com/news/2016/0912/579753.shtml

1、QQ空间超级补丁:

(1)mutilDex机制。QQ空间超级补丁方案是基于android dex分包方案。

分包机制的来由(?)dexopt 、65K限制。

当一个apk在安装的时候,apk中的classes.dex会被虚拟机(dexopt)优化成odex文件,然后才会拿去执行。

(2)ClassLoader 类加载机制。ClassLoader机制是QQ空间超级补丁方案的基石。

tm一个ClassLoader可以包含多个dex文件,每个dex文件就是一个 Element,多个dex文件排列形成一个有序的数组DexElements,当查找某个类时会按照顺序遍历dex文件,然后从当前遍历的dex文件中找类,如果找到了则返回,如果找不到则从下一个dex查找。理论上,如果在不同的dex中有相同的类存在,那么优先选择排在前面的dex文件的类。

(3)副作用:CLASS_ISPREVERIFIED 标志。

防止类被打上CLASS_ISPREVERIFIED标志。

最终空间的方案是往所有类的构造函数里面插入了一段代码,如下:

if (ClassVerifier.PREVENT_VERIFY) {

System.out.println(AntilazyLoad.class);

}

这样当安装apk的时候,classes.dex内的类都会引用一个在不相同dex中的AntilazyLoad类,这样就防止了类被打上CLASS_ISPREVERIFIED的标志了,只要没被打上这个标志的类都可以进行打补丁操作。

优势:

1.  没有合成整包(和微信Tinker比起来),产物比较小,比较灵活

2.  可以实现类替换,兼容性高。(某些三星手机不起作用)

不足:

1. 不支持即时生效,必须通过重启才能生效。

2. 为了实现修复这个过程,必须在应用中加入两个dex!dalvikhack.dex中只有一个类,对性能影响不大,但是对于patch.dex来说,修复的类到了一定数量,就需要花不少的时间加载。对手淘这种航母级应用来说,启动耗时增加2s以上是不能够接受的事。

3. 在ART模式下,如果类修改了结构,就会出现内存错乱的问题。为了解决这个问题,就必须把所有相关的调用类、父类子类等等全部加载到patch.dex中,导致补丁包异常的大,进一步增加应用启动加载的时候,耗时更加严重。

2、微信 Tinker

在编译时通过新旧两个Dex生成差异path.dex。在运行时,将差异patch.dex重新跟原始安装包的旧Dex还原为新的Dex。这个过程可能比较耗费时间与内存,所以我们是单独放在一个后台进程:patch中。

优势:

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

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

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

不足:

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

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

3. 合并时占用额外磁盘空间(占用Rom体积),这边大约是你修改Dex数量的1.5倍(dexopt与dex压缩成jar)的大小)。

微信的这套方案并非没有优缺点,它带来的问题有两个:

占用Rom体积;这边大约是你修改Dex数量的1.5倍(dexopt与dex压缩成jar)的大小。

一个额外的合成过程;虽然我们单独放在一个进程上处理,但是合成时间的长短与内存消耗也会影响最终的成功率

四、AndFix:

AndFix 提供一种运行时在Native修改Field指针的方式,实现方法的替换,达到即时生效无需重启,对应用无性能损耗的目的。

1、原理如图:

2、实现过程:

http://blog.csdn.net/tencent_bugly/article/details/51821722

上一篇下一篇

猜你喜欢

热点阅读