美文网首页
热修复讲解

热修复讲解

作者: 一码立程 | 来源:发表于2018-11-12 16:03 被阅读23次

    1、技术背景

    在开发的过程中,无论是程序员自身写代码的原因,还是产品等其他职位对需求的变动等原因,都会导致我们上线的app会发生一些需要紧急修复的bug,面对这样的问题时候,我们传统的发布流程如下图:

    传统的App发布流程

    此种流程的弊端如下:

    (1)重新发布版本代价太大,且用户下载安装成本太高;

    (2)BUG修复不及时,用户体验较差;

    (3)需求检验测试困难,版本无法进行控制;

    (4)增加各个职位人员的工作量;

    以上所述内容为我们工作真是场景,相比web页面随用随走不留痕迹的特点来说,需要不断的定时更新问题是对我们最大的挑战,所以市场才出现很多web页面和原生结合的App,这些问题对我们的项目造成了较大的困扰,对我们的工作也有很大的不便。

    2.解决方案

    针对以上问题,我们提出采用市场认可度较高的热修复技术来解决:

    引入热修复技术之后,我们的发布流程为这样:

    采用热修复技术后的发布流程

    根据上图,我们可以总结引入热修复技术后对我们开发工作带来的几个优势:

    (1)及时更新,无需重新打包上传应用市场,快速打出补丁包修复bug;

    (2)用户浅感知修复,无需下载应用,代价小;

    (3)发版灵活,可以帮助我们开发更好的协助产品、运营同学的工作;

    3.技术原理

    3.1、市场几款主流热修复框架

    目前市场上的代码修复的框架很多,各个大厂也提供了自己的修复架构和技术,简单的罗列几个:

    (1)微信采用的Tinker;

    (2)QQ空间的Nuwa;

    (3)饿了么的Amigo;

    (4)美团的Robust;

    (5)阿里的XPosted、Andfix 和 Sophix;

    (6)百度的HotFix;

    虽然热修复框架比较多,但是总结这些技术原理实现却基本可以归集两类:底层替换方式和类加载方式;

    两种方案对比优劣势如下:

    (1)底层替换限制较多,兼容性较差,稳定行差,但时效好,加载最快,以手淘的Andfix为代表;

    (2)类加载时效性较差,需要冷启动,但是修复范围广,限制较少,兼容性高,以微信的Tinker技术为代表;

    3.2 类加载方式技术原理:

    微信Tinker采用整体替换DEX的方案实现热修复技术,其原理的大致的过程是:把BUG方法修复以后,单独打包到一个DEX里,采用差量的方式给出patch.dex,然后将patch.dex与应用的classes.dex合并,然后整体替换掉旧的DEX,达到修复的目的。具体实现过程如下图:

    类加载修复实现流程 dex加载合并原理图

    技术重点描述:

    (1)dex:Android内核虚拟机为dalvik(ART)的执行文件,Android程序同样采用Java编写,生成的也是.java文件,所以需要把.java文件转换成.dex文件才能让dalvik运行,所以这中间的步骤由IDE代劳,IDE编译、打包的过程,就是将.java文件转换成.dex文件的过程;5.0之前android 应用中只允许有一个dex文件,dex文件中的方法数量限制在65535之内,大量引入三方的sdk后悔造成无法编译通过,后来google提出了multidex ,支持多个dex文件共存;

    (2)dex修复补丁是一个差量包,内部包含一个或者多个dex文件,也就是说,我们需要把修复过的类文件打包出新的dex文件,供用户下载,在用户下载完成后,与本地的dex代码进行合并,形成全量dex包;

    (3)Android 多个dex 会在一个集合(dexElements)中,加载顺序从头到尾,由dex加载原理图可以看出,补丁包下载结束后,重启应用,会重新编排了包中dex的集合顺序。这样,在虚拟机查找类的时候,会优先找到classes.dex中的类,然后才是classes2.dex、classes3.dex,这样也就实现了我们应用程序的bug 修复;

    总结dex热修复技术特点:

    优势:

    (1)差量包下载,合并包运行,可以减少下载文件的大小,但是减小力度不是很大;

    (2)合成整包,不用在构造函数插入代码,不会在运行期间进行;

    (3)性能提高。兼容性和稳定性比较高;

    (4)开发者透明,不需要对包进行额外处理。

    弊端:

    (1)不支持即时生效,必须通过重启应用的方式才能生效;

    (2)合并时占用额外磁盘空间,对于多DEX的应用来说,如果修改了多个DEX文件,就需要下发多个patch.dex与对应的classes.dex进行合并操作时这种情况会更严重,因此合并过程的失败率也会更高。

    (3)需要给应用开启新的进程才能进行合并,所以该种方式的性能耗费是很大的,最基本的是启动的时间会随着补丁包的大小而变长,如下图所示:

    dex大小与加载时间关系

    3.3  底层替换方式技术原理:

    AndFix提供了一种运行时在Native修改Filed指针的方式,由补丁类的classLoader加载补丁类,在native层针对不同Android架构中的不同的ArtMethod结构调用对应的replaceMethod方法按照定义好的ArtMethod结构一一替换方法的所有信息如所属类、访问权限、代码内存地址等;从而实现方法的替换,达到即时生效无需重启,对应用无性能消耗的目的,基本原理流程如下图:

    底层修复实现原理流程图 底层替换原理图

    底层修复技术重点:

    (1)底层替换方案是在已经加载了的类中直接替换掉原有方法,是在原来类的基础上进行修改的。因而无法实现对与原有类进行方法和字段的增减,因为这样将破坏原有类的结构;

    (2)Java层的每一个方法在虚拟机实现里面都对应着一个ArtMethod的结构体,只要把原方法的结构体内容替换成新的结构体的内容,在调用原方法的时候,真正执行的指令会是新方法的指令;这样就能实现热修复

    (3)Android 手机厂商较多,每个厂商都会对Android 手机进行自己特性的自定义修改,所以就会造成底层代码结构可能发生变化,基于以上原理的话,可能在部分手机无法修复成功;

    总结 底层修复技术的特点:

    优势:

    (1)BUG修复及时;

    (2)补丁包采用差量技术,生成的PATCH体积小(此处的差量包同dex 的差量包本质相同,但是dex是基于类进行对比,而此处是通过方法进行对比形成的差量包);

    (3)对应用无侵入,只是底层修改方法的调用指针,几乎无性能损耗;

    弊端:

    (1)不支持新增字段,也不支持对资源的替换。

    (2)存在一定的限制,比如各个手机厂商对系统的修改和自定义造成底层结构等的变更;(hook方案本身就存在一定的本稳定性)

    3.4 底层修复和类加载的结合

    对于底层修复和类加载修复这两种方案,各有优劣,如果能将二者进行一个结合,可以很好补充对方的不足之处,对此,阿里的Sophix进行了重大的改进,结合两种方案,从补丁生成到应用的各个环节都进行了研究,使得二者能很好地整合在一起。在补丁生成阶段,补丁工具会根据实际代码变动情况进行自动选择,针对小修改,在底层替换方案限制范围内的,就直接采用底层替换修复,这样可以做到代码修复即时生效。而对于代码修改超出底层替换限制的,会使用类加载替换,这样虽然及时性没那么好,但总归可以达到热修复的目的。另外,运行时阶段,Sophix还会再判断所运行的机型是否支持热修复,这样即使补丁支持热修复,但由于机型底层虚拟机构造不支持,还是会走类加载修复,从而达到最好的兼容性。

    总结Sophix的特点:

    优势:

    (1) 补丁即时生效,不需要应用重启;

    (2) 补丁包同样采用差量技术,生成的PATCH体积小;

    (3) 对应用无侵入,几乎无性能损耗;

    (4) 傻瓜式接入。

    弊端:

    (1)AndroidManifest.xml里面的变动无法修复,所以对于四大组件的配置信息的增加修改等内容无法修复;(也可以使用插桩的方式实现,但是会影响代码书写的阅读性)

    (2)对于小问题的修改会及时生效,但是对于修改问题多的时候或者添加比较多的资源文件的时候,还是不能实现及时生效;

    4、方案总结

    热修复技术方案众多,各大长都有自己独特的方案,且进过了几年的发展,该项技术方案也相对成熟,目前市场中的很多应用也都会使用该技术进行升级,但是这些热修复的技术都会存在一个问题是,各个应用商店对其的审核力度不同,苹果可以支持热修复功能,但是苹果应用商店会对热修复项目进行严格的审查且禁止热修复应用上线,Android的应用市场较多,国内市场对其的审核力度较低,一般都会支持,但是GooglePlay市场对热修复应用也会禁止,这样的话,对于公司后期国际化的时候会有一定的影响,当然这个也可以通过技术手段实现,可以针对不同的应用市场做不同的配置机型打包。

    针对市场的几个框架,进行简单的对比,制作如下的对比表格:

    主流热修复框架对比图

    结合以上表格内容对比,如果想要接入热修复功能,乐变和Spohix是两个相对不错的两种方案,但是因为乐变的用户以游戏公司居多,应用量级相对较大,更新频率较多,且目前在其公司的官方上可以了解的内容相对较少,比如集成难度、收费方案等等(这部分内容需要开通服务后才可看到),相比之下,Sophix的开放力度较大,目前可以了解到的内容较多,可以将Sophix作为考虑的第一选项,乐变为第二选项。

    参考资料:

    1、《深入探索Android 热修复技术原理》(阿里官方出版的热修复书籍:强烈推荐

    2、https://help.aliyun.com/product/51340.html(Sophix官方文档)

    3、http://www.tinkerpatch.com/Price(tinker官方文档)

    4、http://m.blog.csdn.net/sinat_14849739/article/details/77148251

    5、http://www.cnblogs.com/deman/p/5814464.html

    6、http://www.infoq.com/cn/articles/Android-hot-fix/

    7、http://www.jianshu.com/p/e3f1fc082b05

    8.https://github.com/Meituan-Dianping/Robust/blob/master/README-zh.md(Rubust)

    相关文章

      网友评论

          本文标题:热修复讲解

          本文链接:https://www.haomeiwen.com/subject/dqpnxqtx.html