Android 热修复方案

1,228 阅读3分钟

一.使用热修复的目的

  • 即时修复紧急bug
  • 冷启动后修复bug(甚至替代功能的发布)

二. 市面上主要的热修复方案有哪些?

总的来说:

  1. AndFix作为native解决方案,首先面临的是稳定性与兼容性问题,更重要的是它无法实现类替换,它是需要大量额外的开发成本的;AndFix热更新原理
  2. Robust兼容性与成功率较高,时效性也很好,但是它与AndFix一样,无法新增变量与类只能用做的bugFix方案;Robust热更新原理
  3. Qzone方案可以做到发布产品功能,但是它主要问题是插桩带来Dalvik的性能问题,以及为了解决Art下内存地址问题而导致补丁包急速增大的。 Qzone热更新原理
  4. Tinker方案也可以做到发布产品功能,兼容性和成功率也较好,唯一不足就是不能即时生效。 Tinker热更新原理

从性能和兼容性两个维度,可以先排除阿里的AndFix和QQ空间的Qzone方案;后面也主要分析美团的Robust和微信的Tinker方案。

三.Robust和Tinker方案的接入使用

1. 美团Robust接入

1. 接入体验

  • 跟着接入文档走和结合demo app接入不难
  • 但是没有补丁的发布平台,需要自己搭建。注意要在发版后保存好mapping.txt和methodsMap.robust这两个文件,打补丁包时会用到。
  • 时效性很好,但只能修复方法中的bug

2. 用到的相关的原理总结:

  1. 编译插桩:Robust热更新系统借鉴Instant Run原理,实现了一个兼容性更强而且实时生效的热更新方案。其基本思路是,Robust热更新系统在一个方法的入口处插入一段跳转代码,当发现某个方法出现bug就跳转执行补丁中的代码,略过原有代码的执行,否则执行原有方法体逻辑。这是官方详细的原理说明文档

反编译后的apk

2.自动化生成补丁补丁制作流程包括:.java ->.class ->.dex ->.smali->.dex 。补丁的生成过程步骤繁杂,与此同时,自动化补丁处理代码风格迥异,需要对Java的各种语法提供支持,无论是泛型、内部类还是Lambda表达式,同时还需要提供对ProGuard的混淆、优化、内联支持,这些极大的增加自动化补丁的难度,这一块比较难理解,有兴趣的可以点击进去瞧瞧

2.bugly热修复接入

1. 接入体验

  • 也是跟着文档和官方demo走,接入的时候遇到一个小坑, bugly热修复打补丁包报异常,需要降级gradle版本每次发版都要保留基准包、混淆配置文件、资源Id文件
  • 有免费的补丁下发平台,也有一些下发策略和针对手机系统的自定义下发策略;
  • 时效性较差,需要杀死当前app进程,重新启动之后即可生效;

2. 用到的相关的原理总结:

简单来说,在编译时,通过新旧两个Dex生成差异path.dex。在运行时,将差异patch.dex重新跟原始安装包的旧Dex还原为新的Dex。这个过程可能比较耗费时间与内存,所以是单独放在一个后台进程:patch中。为了补丁包尽量的小,微信自研了DexDiff算法,它深度利用Dex的格式来减少差异的大小。它的粒度是Dex格式的每一项,可以充分利用原本Dex的信息,而BsDiff的粒度是文件,AndFix/QZone的粒度为class。有兴趣了解更多的同学戳这里

四.本着对用户负责的态度,发布补丁等同于发布版本,它也应该严格执行完整的测试与上线流程