自从热修复框架流行以来,知名的热修复框架由如下几种:
1、AndFix
2、Tinker
3、Nuwa
4、Robust
5、Sophix
6、Amigo
现在还在更新维护的,只有腾讯的Tinker,阿里的Sophix,还有美团的Robust,下图是各个热修复框架的方案对比:
Tinker
服务器端做dex差量,将patch差量包下发到客户端,在5.0以下ART模式虚拟机中,将差量包和原apk中到classes.dex做merge操作,合并成一个新到merge.dex后,将merge.dex插入pathClassLoader的dexElement,QZone的原理和Tinker一致,为了实现差量包的最小化,Tinker自研了DexDiff/DexMerge算法。Tinker还支持资源和So包的更新,So补丁包使用BsDiff来生成,资源补丁包直接使用文件md5对比来生成,针对资源比较大的(默认大雨100kb属于大文件)会使用BsDiff来对文件生成差量补丁。
优点:
1、支持动态下发代码;
2、支持替换So库以及资源;
缺点:
1、不能及时生效,需下次启动;
Tinker已知问题:
1、Tinker不支持修改AndroidManifest.xml文件,Tinker不支持新增四大组件(1.9.0支持新增非export的Activity);
2、由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
3、不支持部分三星android-21机型,加载补丁时会主动抛出"TinkerRuntimeException:checkDexInstall failed";
4、对于资源替换,不支持修改remoteView,如transition动画,notification icon以及桌面图标;
Tinker性能痛点:
1、Dex合并内存消耗在vm head上,容易OOM,最后导致合并失败;
2、如果本身app占用内存已经比较高,可能容易导出app被系统杀掉;
Robust
Robust插件对每个产品代码对每个函数都在编译打包阶段自动插入一段代码,通过判断if(changeQuickRedirect!= null)来确定是否进行热修复,当changeQuickRedirect不为null时,调用patch.dex中同名类的同名方法达到hot fix目的;
生成的patch.dex主要由两个类,PatchesInfoImpl.java和修复后的同名类APatch.java。客户端拿到patch.dex后,用DexClassLoader加载patch.dex,反射拿到PatchesInfoImpl.java这个class,并常见这个class的一个对象,然后通过这个对象知道被替换的是睡,给它的变量ChangeQuickRedirect赋值为patch.dex中的APatch的对象,这样就会去执行补丁包中的方法了。
优点:
几乎不会影响性能(方法调用,冷启动)
支持Android2.3-8.X版本
高兼容性(Robust只是在正常的使用DexClassLoader)、高稳定性,修复成功率高达99.9%
补丁实时生效,不需要重新启动
支持方法级别的修复,包括静态方法;
支持增加方法和类
支持ProGuard的混淆、内联、优化等操作;
缺点:
代码是侵入式的,会在原有的类中加入相关代码
so和资源的替换暂时不支持
会增大apk的提及,平均一个函数会比原来增加17.47个字节,10晚个函数会增加1.67M
会增加少量的方法数,使用了Robust插件后,原来能被ProGuard内联的函数不能被内联了