APP 热修复都懂了,你会 SDK 热修复吗?最全方案在这里!

前言

刚开始要做 SDK 热修复,我是拒绝的 ~

某日,解决完一个线上 bug 后,我冒出了一个念头:让我们的 SDK 也具有热修复的能力呗!

但是查了查,网上资料少、很多热修复方案只针对app……

可是我都拍胸脯向老大夸口了,焉有退缩的道理?!

加上万一以后手抖,出了个什么大 bug 或者兼容问题,我的职业生涯不就要终结了!?

我滴乖乖,保命要紧!还是赶紧做个保底方案吧。

一、背景和目的

我们想实现的效果很简单,如下场景三:

二、技术方案

先说明下,方案没有最好,只有最合适。虽然我最终选定了方案四,但如果各位小伙伴的团队有资源、有其他方案的经验、SDK的热更需求更丰富,可以自行选择其他方案。

方案一:JAR 替换

步骤

从服务端下载 jar -> 通过反射,加载jar -> 创建相关对象并且操作之。

方案参考:
Android SDK热修复机制简析以实现

优缺点

优点:

  1. 无兼容问题

缺点:

  1. 反射消耗性能;
  2. jar 包如果体积大,整个下载就很不友好;
  3. 确定改动的代码范围繁琐,维护麻烦。

方案一改进:子 JAR 替换

步骤

针对 jar 包体积大的情况,我们可以考虑对 sdk 项目进行拆包(拆module),分成小的 jar 包和主包

主包负责反射加载,如果需要热修,下发子 jar 即可,比较轻量。

优缺点

优点:

  1. 只下发子包,轻量

缺点:

  1. 比较适合主包变动小的情况;
  2. 主包和子包耦合性强;
  3. 还是需要用到反射。

方案二:插件化

步骤

将SDK分包,宿主包仅提供 API 和加载核心实现的插件包,插件包就可以热更了。

优缺点

优点:

  1. 灵活

缺点:

  1. 对主项目工程的依赖太大,往往一些基本配置需要依赖于主工程的项目源码;
  2. 使用接入成本高,配置麻烦,而 SDK 的业务接入方需要的是快速接入;
  3. 插件化框架可能会对系统原生代码的运行造成不可预估的影响;
  4. 不得不依赖很多不需要的插件化框架功能。

方案三:业务方热更

走投无路之下,我想起,诶!很多 app 热更方案不是说支持 lib 热更吗!那先作为一个保底方案吧。

步骤

通过业务方 app 热更 lib 包。

优缺点

优点:

  1. 热更权把控在业务方手中,对业务方透明

缺点:

  1. lib 包太大时,下载还是很耗流量的
  2. diff 算法无法计算新旧 lib 的差异,只能整个替换掉
  3. 步骤相当繁琐,如下图:
业务方会杀了你的!

方案四:改造现有 APP 热修复方案

1. 那在选择热修复方案时考虑点有哪些?

  1. 热更项目的需求
  • 只需要简单的方法级别 Bug 修复?
  • 需要资源及 so 库的修复?
  • 需要 Native 的修复?
  • 对平台兼容性要求及成功率要求?
  • 是否需要对补丁包进行管理?
  • 公司资源是否支持商业付费?
  1. 学习及使用成本
  • 集成难度和复杂度
  • 代码侵入性
  • 调试维护
  1. 选择框架的关注点
  • 尽量大厂
  • 性能过关
  • 有专人维护
  • 热度高,开源社区活跃

2. 总结出需要热更的 SDK 特点

  1. 主要是代码热更,无so库、资源更新需求;
  2. 实时性要求高,因为一旦出问题,对业务方的影响极大;
  3. 兼容性要求高,你无法预料到业务方的活跃用户都有啥机型。

3. 那我们赶紧来看下,现有的 APP 热修复方案都有哪些?

3.1 综合优化的产物 —— Sophix(弃)

Sophix 功能完善、开发简单透明,可惜没开源,无法改造。

3.2 底层替换方案(弃)

底层替换方案不可避免地存在兼容问题,弃之。

3.3 类加载方案 —— Tinker

优点:

  1. 用户多
  2. 更新时间新,相比之下,其他有在Github上开源的框架,star数都是7000以下,上次更新时间都在1年前,甚至2年前。

缺点:

  1. dex合成占用ROM较大
  2. 不够实时
  3. 需要改造Application,业务方有感知。(也可以参考 InstantRun 做到不修改 Application 达到替换 Application 的效果,但该方案大量 hook 系统 api,不够稳定,大概有 1/1w 的概率会出现替换失败,所以Tinker最终还是没有使用InstantRun的方式)

还有两个问题,留给大家去思考:

  1. 会不会影响业务方加固?
  2. 和业务方是否冲突?
  1. 打包时替换 Application 标签,插入BootstrapApplication
  2. 运行时 hook 系统api,将 BootstrapApplication 换回 MyApplication
3.4 插桩 —— 美团 Robust

Robust 的原理可以简单描述为:

  1. 打基础包时插桩,在每个方法前插入一段 if(changeQuickRedirect==null)-else 的逻辑;
  2. 加载补丁时,从补丁包中读取要替换的类及具体替换的方法实现,新建 ClassLoader 加载补丁 dex,当目标方法被执行时,此时 changeQuickRedirect != null,方法逻辑流程被改变,而替换掉之前的旧逻辑,达到 fix 的目的。
流程图

优点:

  1. 兼容性最优,兼容加固
  2. 实时生效
  3. 粒度细,支持方法级别的修复
  4. 高稳定性,修复成功率高达99.9%

缺点:

  1. 在编译阶段插件侵入了产品代码,对运行效率、方法数、包体积还是产生了一些副作用。(支持指定某些class无需插入)
  2. so和资源的替换目前暂未实现
  3. 无法新增变量
  4. 没有补丁管理和安全校验,需要开发者自行实现

思考:

  1. 和其他的插桩插件混用是否有冲突?

三、实现

就在我美滋滋地接入 Robust 时,问题来了!

Robust 需要是 Application 才能插桩和打补丁,要用在 SDK 上,还是需要一轮改造的。

如何改造?我将在下篇博文中详解,同时将推出封装好的库,让 SDK 开发者只需 5 分钟即可让自己的 SDK 拥有热修复的能力,敬请期待。

四、除了热更技术本身,我们还应该关心的

当然,我们的焦点并不局限在技术实现上,还有很多值得我们去考虑的:

我们怎么对分发进行控制?对监控数据进行统计?如果补丁引起了崩溃,我们怎么第一时间补救?

1. 精准分发

结合外部维度系统,根据用户维度,比如渠道、系统版本等等做有差别的下发。

2. 数据分析

上线后我们最关心的就是补丁的兼容性和成功率。

  1. 补丁拉取成功率 = 请求补丁成功的用户 / 发起请求补丁的用户
  2. 补丁下载成功率 = 下载补丁成功的用户 / 尝试下载补丁的用户
  3. patch应用成功率 = patch成功的用户 - 回滚的用户 / 补丁下载成功的用户

3. 补丁回滚机制

我们需要支持自动监控崩溃,如果是下发的补丁引起的,则下次启动补丁自动失效,避免扩大影响范围。

以上这些思考,我将会在下篇博文中一一实现,敬请关注!

本篇完成耗时 6 个番茄钟(180 分钟)


我是 FeelsChaotic,一个写得了代码 p 得了图,剪得了视频画得了画的程序媛,致力于追求代码优雅、架构设计和 T 型成长。

欢迎关注 FeelsChaotic 的简书掘金,如果我的文章对你哪怕有一点点帮助,欢迎 ❤️!你的鼓励是我写作的最大动力!

最最重要的,请给出你的建议或意见,有错误请多多指正!

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

推荐阅读更多精彩内容