热修复技术预研

热修复是目前Android市场上比较火的一种“黑科技”,主要用于解决线上重大问题的紧急修复,主流的热修复技术就是“即时无感打补丁”,提升了问题处理能力,优化了用户的使用体验。

热修复技术原理

目前市场上主流的热修复技术,一般分为类加载机制、底层替换机制、Instant Run热插拔机制。

底层替换机制

底层替换方案是直接在Native层修改原有类。传统的底层替换方案是修改虚拟机方法、JNI函数指针和访问修饰符等,这会严重受制于Android手机厂商的定制化系统。Sophix的底层替换方案是在此思想的基础上的优化,针对ArtMethod结构体整体替换,优于之前AndFix针对ArtMethod结构体内方法单独替换的思路。

由于底层替换不会再次加载新类,是直接替换了方法或者类,可立即生效不需重启App。

类加载机制

在APP重新启动后,ClassLoader会遍历Element数组dexElements(每个dex文件对应一个Element),找到对应类就返回,不会再去加载有Bug的那个类了。基于此,我们把这个修复后的文件放在Dex文件中,并让其排在dexElements数组靠前位置即可。

类加载机制需要重启方有效,因为类无法被卸载,只有重新调用ClassLoader加载类,即需要重启App,不能即时生效。

Instant Run热插拔机制

在此机制下,编译打包阶段自动为每个class都增加一个类型为ChangeQuickRedirect的静态成员,而在每个方法前都插入了使用changeQuickRedirect相关的逻辑,当changeQuickRedirect不为null时,会执行access$dispatch方法,最终执行到替换类对应方法的新逻辑,达到fix的目的。

热插拔机制的热修复优势在于即时生效,但其使用了插桩思想,性能开销很大。

补充说明下Instant Run的热插拔、温插拔、冷插拔的概念。

  • HotSwap(热插拔):修改方法实现后代码可以实时生效,不需要重启App也不需要重启activity,只要加载补丁之后就可以马上生效。通常情况下,热插拔只适用于方法体内部的逻辑改变。
  • WarmSwap(温插拔):主要针对于需要修改或删除资源的情况。温插拔不需要重启App,但是需要重启当前的activity后才能生效。仅适用于开发阶段。
  • ColdSwap(冷插拔):主要针对于改变了类的结构、继承关系、实现接口等情况,此时因为类结构本身被改变了,需要重新去加载这个类,所以需要重启App之后才能生效。

热修复方案对比

基于类加载机制的热修复技术有:Tinker、QQ空间超级补丁、手机QQ的QFix、Amigo和Nuwa等。

  • QQ空间超级补丁/Nuwa:将补丁包放在Element数组的第一个元素得以优先加载。
  • Tinker:将新旧apk做了diff,并将得到的patch.dex与手机中的apk的classes.dex合并,生成新的class.dex,并在运行时通过反射将classes.dex放在Element数组的第一个元素。
  • Amigo:将补丁包中的每个dex对应的Element取出来,之后形成新的Element数组,在运行时通过反射用新的Element数组替换掉现有的Element数组。

基于底层替换机制的热修复技术有:AnFix,Dexposed,阿里百川,Sophix。

基于Instant Run机制的热修复技术有:Robust和Aceso。

目前市场上较成熟的热修复方案,优劣对比如下表。

方案对比 Sophix Tinker Amigo
DEX修复 同时支持即时生效和冷启动修复 冷启动修复 冷启动修复
资源修复 差量包,不用合成 差量包,需要合成 全量包,不用合成
SO库更新 插桩实现,开发透明 替换接口,开发不透明 插桩实现,开发透明
性能损耗 低,仅冷启动情况下有些损耗 高,有合成操作 低,全量替换
四大组件 不能修复 不能修复 能修复
生成补丁 直接选择已经编好的新旧包在本地生成 编译新包时设置基线包 上传完整新包到服务端
补丁大小
接入成本 傻瓜式接入 复杂 一般
Android版本 全部支持 全部支持 全部支持
安全机制 加密传输及签名校验 加密传输及签名校验 加密传输及签名校验
服务端支持 支持服务端控制 支持服务端控制 支持服务端控制

四大组件的修复,须要在 AndroidManifest.xml 里预先插入代理组件,并尽可能声明所有权限,会造成原有APP更多臃肿代码,侵入性强。

调研结果

建议采用阿里体系的Sophix热修复方案,主要原因如下:

  • 全量替换ArtMethod结构体,忽略内部结构差异,适配全版本、多平台系统定制(已验证兼容Android O版本);
  • 结合类加载机制思想,优化dex粒度,采用dex文件级别的类插桩方案,降低性能损耗;
  • 联合底层替换机制和类加载机制,优势互补,支持根据代码变动情况或机型支持情况灵活选择最适合方案。
  • 采用别于Instant Run温插拔的机制,直接在原有的AssetManager对象上进行重构变动资源的补丁包,不影响外在引用逻辑。

简单说就是:人无我有,人有我优。所以建议Sophix。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容