热修复是不少开发者关心的技术,8月27日晚,阿里百川组织了“百川解码”在线直播,以“热修复的坑和阿里的解”为主题,邀请了三位业界嘉宾对热修复技术进行了探讨,并介绍了阿里百川全面接受公测的热修复解决方案:阿里百川HotFix,就网友提出的相关问题进行了解答。本文是这次直播的精彩回顾。编程
嘉宾简介数组
歩川,阿里巴巴资深开发工程师,《让App像Web同样发布新版本》一文做者,在OPPO从事Android Framework两年,腾讯QQ空间工做一年半,热衷研究安卓热补丁方案。目前在手机淘宝终端架构,主要负责动态部署加强和优化、存储相关工做。安全
刘昭,中华英才网Android技术负责人,具备丰富的移动开发经验,崇尚开源社区文化,关注性能优化、研发效率、热修复、插件化、数据驱动等,善于评估技术方案,解决疑难杂症。性能优化
泽胤,阿里巴巴无线技术专家,阿里百川HotFix项目负责人,无线事业部初创技术员工之一。经历阿里巴巴无线技术从小到大的整个过程,参与过多个无线的重要项目,包括无线的H5建站,无线统一接入层,阿里的无线PUSH系统,以及初版的Android客户端等。主要技术方向是在线高并发和高可用性的维护与实现。网络
热修复是什么数据结构
刘昭认为,热修复是在应用的App包发布到市场以后,出现了Bug,无需替换包来进行在线更新的一种技术,对用户是无感知的。架构
泽胤认为,谈到热修复,就应该和动态部署的概念进行区分。热修复是特指对微小改动进行修复的一个技术,它强调快速和无感的修复。而动态部署会复杂更多,它涵盖的东西也更多,但核心的技术仍是热修复技术。并发
步川认为,热修复能够从技术上来理解并和动态部署进行区分。他提到,目前广义上有两种方案能够实现代码的替换,一种是类的替换,基于Classloader,另外一种是方法的替换,而这两种方式各有优缺点。编程语言
方法的替换:只能替换方法的内容,因此不可以对要patch的类进行方法的新增和删除;但同时,方法的替换能够在应用不重启的状况下实现。它包小、快速、功能单1、比较轻量,这种方案是热修复。
类的替换:能够修改类结构,功能更加的强大;可是必需要重启一次才会有效,由于已经加载过的类是不可以被替换的。这种方案叫作“动态部署”。它几乎可以适应任何代码的变动,因此很适合进行业务功能的迭代。函数
热修复技术对比
目前,业内有不少的热修复方案,步川就热修复技术向观众进行了对比讲解。他提到,从广义上来说,热修复的实现方式能够被分为类的替换和方法的替换。
类的替换
如图1所示,APK包中包含了代码和资源,代码存放在classes.dex中,资源存放在APK的res目录下,系统会经过ClassLoader装载classes.dex来进行类加载。若是有多个classes.dex,那么这多个classes.dex会在ClassLoader中会用数组的形式来进行组织,而后从前日后进行遍历查找。
图1
一种具体的方案如图2所示,是利用多dex从前日后遍历的有序特性,把patch.dex插入到数组的最前面,对patch进行有限查找,达到替换的目的,这时候就会出现preverify问题,为了绕过这个问题,就必须往每一个类的构造函数里面进行插桩防止安装期间的校验,把校验从编译期间移动到了运行期间,致使运行期间每加载一个类,都要进行校验和优化,下降了运行性能。
图2
刘昭认为,这种方案利用了ClassLoader,思想是比较好的,可是若是工程中的类比较多,就会在性能上形成比较大的影响。同时,有可能会致使patch包比较大。
步川提到,为了解决上述性能问题,出现了另外一种方案,如图3所示:就是全量替换dex,下发一个patch.dex,而后把原来的dex和下发的patch.dex,合成一个新的全量dex,这个dex会全量替换原来的dex,最终本质上也只会在这个全量的dex中查找,从而不会出现preverify问题,因此这种方案不用插入构造函数,不会影响性能。可是,这种方案的包也可能会比较大,只改动了一行代码,也必须合成一个全量的dex,如图4所示,而后再dexopt出一个全量的odex。
图3
图4
方法的替换
如图5所示,方法的替换的原理以下:在Android底层,有个数据结构记录着类的信息,好比成员变量的个数,方法的个数,每一个方法的code执行地址,程序运行的时候会根据这个地址跳转到具体的code区域执行代码。方法的替换就是替换这些地址,把地址指向另外一个类的方法,从而达到了替换的目的。这种方式的包比较小,并且也不须要插桩来影响性能,可是它没法修改类的结构(好比方法数的增删),并且有可能会有兼容性问题,例如厂商修改了类和方法的底层结构。
图5
因此基于他们的优势和限制,区分热修复和动态部署这两种场景,能够在这两种不一样的状况下,选择最优的方案,达到修复的目的。
如何选择热修复技术方案
刘昭认为,热修复技术方案的选择应该对应具体的使用场景。在patch包的数量、大小方面,HotFix是占优点的;可是HotFix不能新增类、新增字段(下文泽胤有回应),从这个角度考虑,ClassLoader更好,可是会有必定的性能损耗;合成dex的方式,则须要知道用户手机的ROM有多大,能不能提供20多M的空间来。
基于AndFix的阿里百川HotFix作了哪些优化工做
阿里百川HotFix是基于AndFix的,泽胤提到,手机淘宝(下文简称“手淘”)对于Andfix实践了大约一年左右,在工程和技术上作了一些改善,提升了其在稳定性、周边工具链的性能和稳定性等方面的表现,使得这项技术更加成熟,同时也解决了不能新增类等问题,并成功落地手淘App。
具体的优化工做包括:在产品化方面,接入简单,2行代码便可接入,通常开发者1个小时便可彻底跑通流程,大大下降工程成本;提供了相对完善的周边工具链,经过后台操做自由控制patch发布,最大化保证用户体验。针对patch打包慢的问题进行优化,持续在工具链方面进行优化;在“打包工具交互”方面,开发了一个独立的可执行文件,能够在工程里面,用GRADLE、ANT中集成,甚至在JENKINS里面去执行,提升了灵活性。
在产品化方面,接入简单,2行代码便可接入,通常开发者1个小时便可彻底跑通流程,大大下降工程成本;提供了相对完善的周边工具链,经过后台操做自由控制patch发布,最大化保证用户体验。
在安全方面,泽胤也作了说明:第一,阿里会提供一个私有RSA加密的功能,开发者在本地打出包之后用本身的RSA密钥对中的私钥加密,而后上传百川平台,再在SDK中放置本身的公钥做为解码用,这样上传的内容彻底加密确保绝对的信息安全,且不会被阿里看到;第二,传输层面,在设计上采用两级的加密,动态密钥和静态密钥相结合,所以网络拦截没法窃取到包内容。
热修复的将来
从商业价值上来说,开发者目前很是须要热修复技术,因此有必定的价值,可是将来,若是官方提供相应的功能,或者说React Native 等技术减弱了开发者对热修复技术的依赖,则会对热修复的技术产品形成冲击。对于这样的状况,泽胤认为,做为技术人员,要不断学习进步。一项技术若是没有了被使用的价值,那么它是应该被淘汰掉的,例如历史上不少编程语言或者技术的消亡。泽胤表示,产品的迭代和消亡也是很正常的。很乐意看到有新的,知足开发者需求的技术能够代替老的技术。
步川认为,从方案讲,热修复和动态部署不是互相排斥的,在特定的场景下二者均可以作到最优,配合使用更佳。手淘同时使用这两项技术,用热修复解决Bug,用动态部署来迭代业务,相互配合好则会达到很完美的状态。
刘昭提出,Android Studio 2.0以后,提供了Instant Run这样的功能,从思想上来说是很是好地解决了热修复patch的问题,以后的热修复有没有可能借鉴其思想?对于这个问题,步川认为,Instant Run的更新力度比较大,同时又在代码中增长了预埋逻辑,侵入性比较大。若基于Class Loader来开发一个工具,或许会更简单。
阿里百川HotFix开始公测
泽胤提到,市场上缺乏阿里百川HotFix这样的产品,虽然热修复原理解析不少,可是真正难的是把这项技术作成熟、作稳定。基于手淘App这个大平台,由工程实践出来的阿里百川HotFix产品,能够推出独立的服务来知足市场上的需求。泽胤提到,阿里百川会有专门的团队持续跟进该产品,解决问题,吸纳用户意见。
阿里百川HotFix从直播当晚开始正式进行公测,你还没申请公测?
来吧点我!阿里百川HotFix公测申请