现在还在更新维护的就腾讯的Tinker, 阿里的Sophix,美团的Robust
1、Tinker
服务端做dex差量,将差量包下发到客户端,在ART模式的机型上本地跟原apk中的classes.dex做merge,merge成为一个新的merge.dex后将merge.dex插入pathClassLoader的dexElement,原理类同Q-Zone,为了实现差量包的最小化,Tinker自研了DexDiff/DexMerge算法。Tinker还支持资源和So包的更新,So补丁包使用BsDiff来生成,资源补丁包直接使用文件md5对比来生成,针对资源比较大的(默认大于100KB属于大文件)会使用BsDiff来对文件生成差量补丁
优点:
支持动态下发代码
支持替换So库以及资源
缺点:
不能即时生效,需要下次启动
Tinker已知问题:
Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件(1.9.0支持新增非export的Activity);
由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
在Android N上,补丁对应用启动时间有轻微的影响;
不支持部分三星android-21机型,加载补丁时会主动抛出"TinkerRuntimeException:checkDexInstall failed";
对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标。
Tinker性能痛点:
Dex合并内存消耗在vm head上,容易OOM,最后导致合并失败。
如果本身app占用内存已经比较高,可能容易导致app本系统杀掉。
github地址:https://github.com/Tencent/tinker
demo地址: https://github.com/Tencent/tinker/tree/dev/tinker-sample-android
接入指南: https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
还有一个已经封装好的傻瓜式接入方案,对Tinker进行了封装,也实现了后台,但是需要钱,自己玩玩可以:
http://tinkerpatch.com/Docs/intro
2、Robust
Robust 插件对每个产品代码的每个函数都在编译打包阶段自动的插入了一段代码。通过判断 if(changeQuickRedirect != null) 来确定是否进行热修复,当 changeQuickRedirect 不为 null 时,调用 patch.dex 中同名类的同名方法达到 hotfix 的目的。
生成的patch.dex 中有两个主要类,PatchesInfoImpl.java 和修复后的同名类 APatch.java。客户端拿到patch.dex 后,用DexClassLoader 加载patch.dex,反射拿到PatchesInfoImpl.java 这个 class。并创建这个class 的一个对象。然后通过这个对象知道被替换的是谁,给它的变量changeQuickRedirect 赋值为 patch.dex 中的 APatch 的对象,这样就会去执行补丁包中的方法了。
具体可以看下这个:https://zhuanlan.zhihu.com/p/22495059
优点:
几乎不会影响性能(方法调用,冷启动)
支持Android2.3-8.x版本
高兼容性(Robust只是在正常的使用DexClassLoader)、高稳定性,修复成功率高达99.9%
补丁实时生效,不需要重新启动
支持方法级别的修复,包括静态方法
支持增加方法和类
支持ProGuard的混淆、内联、优化等操作
缺点:
代码是侵入式的,会在原有的类中加入相关代码
so和资源的替换暂时不支持
会增大apk的体积,平均一个函数会比原来增加17.47个字节,10万个函数会增加1.67M。
会增加少量方法数,使用了Robust插件后,原来能被ProGuard内联的函数不能被内联了
开源地址: https://github.com/Meituan-Dianping/Robust
集成指南:https://github.com/Meituan-Dianping/Robust/blob/master/README-zh.md