课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
烟台达内培训小编讯,早在6月份微信客户端技术团队就透露了它的存在,并介绍了其原理,有人根据原理做了相关的demo,另外饿了么的热补丁框架amigo据说也参考了它,因此,Tinker的开源可以说是众望所归,在国内众多热补丁框架中独树一帜,引人瞩目。
框架作者张绍文撰文介绍了研发Tinker过程中的一些挑战和思考,本文是其第一篇,介绍Tinker v1.0的设计思路和经验。
热补丁技术背景
在笔者看来Android热补丁技术应该分为以下两个流派:
Native,代表有阿里的Dexposed、AndFix与腾讯的内部方案KKFix;
Java,代表有Qzone的超级补丁、大众点评的nuwa、百度金融的rocooFix, 饿了么的amigo以及美团的robust。
Native流派与Java流派都有着自己的优缺点,它们具体差异大家可参考上文。事实上从来都没有最好的方案,只有最适合自己的。
对于微信来说,我们希望得到一个“高可用”的补丁框架,它应该满足以下几个条件:
稳定性与兼容性;微信需要在数亿台设备上运行,即使补丁框架带来1%的异常,也将影响到数万用户。保证补丁框架的稳定性与兼容性是我们的第一要务;
性能;微信对性能要求也非常苛刻,首先补丁框架不能影响应用的性能,这里基于大部分情况下用户不会使用到补丁。其次补丁包应该尽量少,这关系到用户流量与补丁的成功率问题;
易用性;在解决完以上两个核心问题的前提下,我们希望补丁框架简单易用,并且可以全面支持,甚至可以做到功能发布级别。
在“高可用”这个大前提下,微信对当时存在的两个方案做了大量的研究:
Dexposed/AndFix;最大挑战在于稳定性与兼容性,而且native异常排查难度更高。另一方面,由于无法增加变量与类等限制,无法做到功能发布级别;
Qzone;最大挑战在于性能,即Dalvik平台存在插桩导致的性能损耗,Art平台由于地址偏移问题导致补丁包可能过大的问题;
在2016年3月,微信为了追寻“高可用”这个目标,决定尝试搭建自己的补丁框架——Tinker。Tinker框架的演绎并不是一蹴而就,它大致分为三个阶段,每一阶段需要解决的核心问题并不相同。而Tinker v1.0的核心问题是实现符合性能要求的Dex补丁框架。
Tinker v1.0-性能极致追求之路
为了稳定性与兼容性,微信选择了Java流派。当前最大难点在于如何突破Qzone方案的性能问题,这时通过研究Instant Run的冷插拔与buck的exopackage给了我们灵感。它们的思想都是全量替换新的Dex。
简单来说,我们通过完全使用了新的Dex,那样既不出现Art地址错乱的问题,在Dalvik也无须插桩。当然考虑到补丁包的体积,我们不能直接将新的Dex放在里面。但我们可以将新旧两个Dex的差异放到补丁包中,这里我们可以调研的方法有以下几个:
BsDiff;它格式无关,但对Dex效果不是特别好,而且非常不稳定。当前微信对于so与部分资源,依然使用bsdiff算法;
DexMerge;它主要问题在于合成时内存占用过大,一个12M的dex,峰值内存可能达到70多M;
DexDiff;通过深入Dex格式,实现一套diff差异小,内存占用少以及支持增删改的算法。
如何选择?在“高可用”的核心诉求下,性能问题也尤为重要。非常庆幸微信在当时那个节点坚决的选择了自研DexDiff算法,这过程虽然有苦有泪,但也正是有它,才有现在的Tinker。