为什么需要热补丁
从上面的定义来看,热补丁节省Android大量应用市场发布的时间。同时用户也无需重新安装,只要上线就能无感知的更新。看起来很美好,这是否可以意味我们可以尽量使用补丁来代替发布呢?事实上,热补丁技术当前依然存在它的局限性,主要表现在以下几点:
既然补丁技术无法完全代替升级,那它适合使用在哪些场景呢? 一. 轻量而快速的升级热补丁技术也可以理解为一个动态修改代码与资源的通道,它适合于修改量较少的情况。以微信的多次发布为例,补丁大小均在300K以内,它相对于传统的发布有着很大的优势。
正因如此,补丁技术非常适合使用在灰度阶段。在过去,我们需要在正式发布前保证所有严重的问题都已经得到修复,这通常需要我们经过三次以上的灰度过程,而且无法快速的验证这些问题在同一批用户的修复效果。利用热补丁技术,我们可以快速对同一批用户验证修复效果,这大大缩短我们的发布流程。
二. 远端调试一入Android深似海,Android开发的另外一个痛是机型的碎片化。我们也许都会遇到'本地不复现','日志查不出','联系用户不鸟你'的烦恼。所以补丁机制非常适合使用在远端调试上。即我们需要具备只特定用户发送补丁的能力,这对我们查找问题非常有帮助。
三. 数据统计数据统计在微信中也占据着非常重要的位置,我们也非常希望将热补丁与数据统计结合的更好。事实上,热补丁无论在普通的数据统计还是ABTest都有着非常大的优势。例如若我想对同一批用户做两种test, 传统方式无法让这批用户去安装两个版本。使用补丁技术,我们可以方便的对同一批用户更换补丁版本。 四. 其他事实上,Android官方也使用热补丁技术实现Instant Run。它分为Hot Swap、Warm Swap与Cold Swap三种方式,大家可以参考英文介绍,也可以看参考文章中的翻译稿。最新的Instant App应该也是采用类似的原理,但是Google Play是不允许下发代码的,这个海外App需要注意一下。 微信热补丁技术的演进之路在了解补丁技术可以与适合做什么之后,我们回到技术本身。由于Dexposed无法支持全平台,并不适合应用到商业产品中。所以这里我们只简单介绍Andfix、Qzone、微信几套方案的实现,以及它们方案面临着的问题,大家也可以参考资料中的各大热补丁方案分析和比较一文。 一. AndFixAndFix采用native hook的方式,这套方案直接使用
二. QzoneQzone方案并没有开源,但在github上的Nuwa采用了相同的方式。这个方案使用classloader的方式,能实现更加友好的类替换。而且这与我们加载Multidex的做法相似,能基本保证稳定性与兼容性。具体原理在这里不再细说,大家可以参考'安卓App热补丁动态修复技术介绍'这篇文章。 本方案为了解决
总的来说,Qzone方案好处在于开发透明,简单,这一套方案目前的应用成功率也是最高的,但在补丁包大小与性能损耗上有一定的局限性。特别是无论我们是否真正应用补丁,都会因为插桩导致对程序运行时的性能产生影响。微信对于性能要求较高,所以我们也没有采用这套方案。 三. 微信热补丁方案有没有那么一种方案,能做到开发透明,但是却没有Qzone方案的缺陷呢?Instant Run的冷插拔与buck的exopackage或许能给我们灵感,它们的思想都是全量替换新的Dex。即我们完全使用了新的Dex,那样既不出现Art地址错乱的问题,在Dalvik也无须插桩。当然考虑到补丁包的体积,我们不能直接将新的Dex放在里面。但我们可以将新旧两个Dex的差异放到补丁包中,最简单我们可以采用BsDiff算法。
限于篇幅,这里对Dex、library以及资源的更多技术细节并没有详细的论述,这里希望放在后面的单独文章中。我们最后从整体比较一下这几种方案:
事实上,一个完整的框架应该也是一个容易使用的框架。Tinker对补丁版本管理、进程管理、安全校验等都有着很好的支持。同时我们也支持gradle与命名行两种接入方式。希望在不久的将来,它可以很快的跟大家见面。 微信的热补丁应用现状上一章节我们简单比较了各个热补丁的技术方案,它们解决了如何生成与加载补丁包的问题。但一个完善的热补丁系统不应该仅限于此,它还需要包括以下几个方面:
一. 网络通道现状网络通道负责的将补丁包交付给用户,这个包括特定用户与全量用户两种情况。事实上,微信当前针对热补丁有以下三种通道更新:
事实上,对于大部分的应用来说,假设不实现push通道,CDN+pull通道实现起来还是较为容易。 二. 上线与管理平台现状上线与管理平台主要为了快速上线,管理历史记录,以及监控补丁的运行情况等(界面比较丑陋,因为我们木有美工啊)。
三. 补丁成功率现状
使用Qzone方案,微信补丁在10天后的应用成功率大约在98.5%左右。使用Tinker大约只有95.5%左右,主要原因在于空间不足以及后台进程被杀。在这里我们也在尝试使用重试的方式以及降低合成的耗时与内存,从而提升成功率。 热补丁技术发展的很快,Android推出的Instant App也令人期待。但是在国内,似乎我们还是指望自己更靠谱一点。每一个的应用的需求都不太一致,这里大致讲了一些微信的实践经验,希望对大家有帮助。 未来工作随着微信部门内从“单APP”向“多APP”演进,微信也正在迈入开源化的开发实践。我们希望将各个功能组件化,从而做可以到快速复制与应用。微信的热补丁框架“Tinker”当前也在经历从微信分离,又合入到微信的过程。希望在不久的将来,我们也可以将“Tinker”以及微信中一些其他的组件开源出去。 |
|