实际需求
- 能解决大部分紧急修复场景。
- 用户无感知。冷/热启动,生效所耗时长及资源(性能),patch体积。
- apk无感知。对原有项目侵入性低。
以下是目前流行的四个方案:Tinker/Andfix/Robust/QQ空间
1. 微信Tinker
- 优点
- 支持布局及资源文件的修改
- 可修改类的private方法及变量
- 官方称成功率挺高
- 可设置一些Log/reporter/exceptionHandler进行补丁加载结果的干预。定制化程度高。
- 支持混淆及多渠道打包
- Dalvik全量合成新的Dex,那样既不出现Art地址错乱的问题,在Dalvik也无须插桩,解决了插桩带来的性能损耗;Art平台合成small dex,解决了全量合成方案占用Rom体积大, OTA升级以及Android N的问题;有效防止了qq空间导致的加载效率下降问题,但是打开时很耗资源。
- 大部分情况下补丁仅仅1-20K,解决由于补丁包可能过大的问题;
- Tinker目前维护团队是3人,一直有更新。Andfix从去年年底没更新过。
- 缺点
- 不支持即时生效;
- 需要给应用开启新的进程才能进行合并,并且很容易因为内存消耗等原因合并失败;
- 合并时占用额外磁盘空间,对于多DEX的应用来说,如果修改了多个DEX文件,就需要下发多个patch.dex与对应的classes.dex进行合并操作时,这种情况会更严重。
- 不足
- Tinker库中不能修改的类一共有26个,即com.tencent.tinker.loader.*类。加上Appliction类,只有26个类是无法通过Tinker来修改的。支持ApplicationLike代理类的修改。
- 生效时间需要13秒左右(估计是合成dex的时间),第一次加载成功后可选择是否立即自动杀掉应用。
官方说法
由于原理与系统限制,Tinker有以下已知问题:
1.Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件;
2.由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
3.在Android N上,补丁对应用启动时间有轻微的影响;
4.不支持部分三星android-21机型,加载补丁时会主动抛出"TinkerRuntimeException:checkDexInstall failed";
5.对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标。
- 使用提示
-
优化冷启动的体验
为了加快补丁应用同时保持用户体验,在SampleResultService.java在应用退入后台或手机灭屏时,才杀掉进程。你也可以在杀掉进程前,直接通过发送broadcast或serviceIntent的方式尽快的重启进程。
2. 阿里andfix
- 优点
- 即时生效;
- 不侵入打包, 性能无损耗;
- 应用广,兼容性问题不大。
- 缺点
- 成功率在50%左右。
- 不支持新增类方法/字段,以及修改<init>方法,也不支持对资源的替换。
- 未来维护性低。
原理
底层替换方案是在已经加载了的类中直接替换掉原有方法,是在原有类的基础上进行修改的。因而无法实现对原有类进行方法和字段的增减,这样将破坏原有类的结构。
主要是修改虚拟机方法实体的具体字段,运行时在Native修改Filed指针的方式,实现方法的替换流程
1.app初始化时加载当前版本下的所有apatch文件。
2.通过注解获取到补丁文件的补丁方法。
3.通过反射获取对应的bugMethd.
4.通过c++层,拿到库文件句柄,并得到对应文件的class对象,得到新旧方法的指针,最后将新方法指针指向目标方。
备注: 在加载类时跳过了类装载过程直接设置为初始化完毕,所以不支持新增静态变量和方法。使用说明
如果之前版本存在bug,并且添加过对应的bug补丁的,再次升级的需要把bug修复,此时需要将init中对应的版本号也需要升级,不然会加载之前存放在data中的补丁文件。修复能力
- 补丁注意事项
1.如果之前版本存在bug,并且添加过对应的bug补丁的,再次升级的需要把bug修复,此时需要将init中对应的版本号也需要升级,不然会加载之前存放在data中的补丁文件。
2.一个补丁文件可以修复多个bug。
3.如果一个版本第一次加载了补丁,第二次修改另外一个bug,补丁仍然是相同的名字,那么此次新添加的补丁将无效就需要删除之前的补丁。但是可以同时存在多个不一样名字的补丁,并且加载按照时间顺序来加载。
3. 美团Robust
优点
兼容性高,未反射注入,实时生效。缺点
- 原来能被ProGuard内联的函数不能被内联了,所以可能导致方法数的增加,原来没超过65536但是后面可能就操作了65536限制,同时apk的体积也会一定程度的增大;
- so和资源的替换暂时不支持;
- 侵入式打包。在编译阶段有插件侵入了产品代码,对运行效率、方法数、包体积还是产生了一些副作用。这也是我们下一步努力的方向。
4. QQ空间
优点
兼容性高。实现更加友好的类替换。(不太懂实现手段)缺点
- 不支持实时生效;
- davilk下类加载性能问题;
- art下补丁包包很大;
- 侵入式打包。采用插桩的方式给所有类插入不会真正运行的代码,防止类打上 preverify 标志。
Sophix及热修复原理可查阅
Sophix及热修复原理介绍