前言

刚开始要做 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. 热更项目的需求
  2. 只需要简单的方法级别 Bug 修复?
  3. 需要资源及 so 库的修复?
  4. 需要 Native 的修复?
  5. 对平台兼容性要求及成功率要求?
  6. 是否需要对补丁包进行管理?
  7. 公司资源是否支持商业付费?
  8. 学习及使用成本
  9. 集成难度和复杂度
  10. 代码侵入性
  11. 调试维护
  12. 选择框架的关注点
  13. 尽量大厂
  14. 性能过关
  15. 有专人维护
  16. 热度高,开源社区活跃

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. 和业务方是否冲突?

方案参考: 基于Tinker的SDK全局热更新方案(全网唯一)
扩展: InstantRun 如何动态替换 Application,总结起来就两步:
- 打包时替换 Application 标签,插入BootstrapApplication
- 运行时 hook 系统api,将 BootstrapApplication 换回 MyApplication

3.4 插桩 —— 美团 Robust

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

优点: 1. 兼容性最优,兼容加固 2. 实时生效 3. 粒度细,支持方法级别的修复 3. 高稳定性,修复成功率高达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 的简书和掘金,如果我的文章对你哪怕有一点点帮助,欢迎 ❤️!你的鼓励是我写作的最大动力!

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

插件修复数据_APP 热修复都懂了,你会 SDK 热修复吗?最全方案在这里!相关推荐

  1. 走嵌入式方向,一定要软硬件都懂吗?

    知乎上看到这么一个问题:走嵌入式方向,一定要软硬件都懂吗? 如下写点个人看法,全文约2432个字,阅读时间约10分钟,仅供参考-- 一  信息时代知识爆炸 从以瓦特发明蒸汽机为代表的第一次工业革命,到 ...

  2. 华为 AI 芯片诞生;马云重当中国首富;微软修复数据删除 Bug | 极客头条

    「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有料的新闻资讯,让所有技术人,时刻紧跟业界潮流. 快讯速知 华 ...

  3. 有了这个数据强一致“利器”,DBA们轻松修复数据对加班“say no”

    本文分享自华为云社区<HDC.Cloud2021|华为云GaussDB让开发者们不再加班修复数据>,原文作者:心机胖. 众所周知,智能时代的来临正是因为开发者们用一行行代码铸就了千行百业向 ...

  4. 北京华客服务器数据恢复中心怎么样,北京修复数据

    北京修复数据 2021-05-07 移动硬盘数据修复服务器硬盘离线数据丢失如何恢复?最近接手了一个服务器硬盘的数据恢复案例.用户带的服务器是IBM服务器,有四个windows操作系统的硬盘.服务器硬盘 ...

  5. sd卡数据恢复:sd卡损坏这样修复数据

    sd卡损坏如何修复数据?很多数据存储设备使用久了之后,都容易出现损坏的情况,从而导致里面的数据丢失.乱码,大家都知道怎么修复受损的sd卡吗?丢失的数据又该如何恢复呢?下面就一起来了解下. 首先我们可以 ...

  6. HBase 2.0之修复工具HBCK2,修复数据

    1.起因 此次修复数据情况是:服务器中毒导致HBASE异常关闭, 启动各种错误,实在没搞懂就清理了ZK关于HBASE的目录(rmr /hbase 建议先看原因,实在不行在做这个删除ZK操作,不对任何人 ...

  7. mysql数据库检表_MYSQL数据库检查数据表和修复数据表

    数据库在运行中,会因为人为因素或一些不可抗力因素造成数据损坏.所以为了保护数据的安全和最小停机时间,我们需制定详细的备份/恢复计划,并定期对计划的有效性进行测试. 结合MySQL服务器的运行机制和所提 ...

  8. oracle模块损坏,Oracle中模拟及修复数据块损坏

    Oracle中模拟及修复数据块损坏,itpub link: http://www.itpub.net/showthread.php?threadid=201766[@more@]Oracle中模拟及修 ...

  9. Android热更新十:自己写一个Android热修复

    很早之前就想深入的研究和学习一下热修复,由于时间的原因一直拖着,现在才执笔弄起来. Android而更新系列: Android热更新一:JAVA的类加载机制 Android热更新二:理解Java反射 ...

最新文章

  1. 研三学生举报导师强迫学生延期毕业,事件再三反转,学校回应了!
  2. python线性表顺序存储实现_数据结构——基于C的线性表的顺序存储结构的基本操作的实现...
  3. 万网 php session,Session
  4. 漏洞战争软件漏洞分析精要 学习笔记
  5. 理解 | 理解a: float=10
  6. 记一次 .NET 某消防物联网 后台服务 内存泄漏分析
  7. php 留言板分页显示,php有分页的留言板,留言成功后怎么返回当前页?
  8. 西方餐厅的顶级食材,被中国人干到了“白菜价”
  9. Docker教程(一) Docker入门教程
  10. MTK 驱动开发(24)---camera模块的制作
  11. Xmind快捷键笔记
  12. 利用CEF山寨一个翻译器
  13. python 爬取妹子图
  14. myBatis --(3)数据的增删改查
  15. thinkphp出现此页面不能重定向
  16. iPhone如何截长图?iPhone长截图教程
  17. 72分辨率下1厘米等于多少像素,300分辨率下1厘米等于多少像素
  18. C语言基础知识入门和C语言入门基础知识大全
  19. docker-compose设置redis密码
  20. 人工智能/机器学习/深度学习:学习路线图

热门文章

  1. CentOS下ZooKeeper单机模式、集群模式安装
  2. android 蒙版图片带拖动_Android实现蒙版弹出框效果
  3. Spring Cloud Config入门(本地配置)
  4. 《大数据日知录:架构与算法》前言
  5. 【最全解析】1050 螺旋矩阵 (25分)
  6. C语言:L1-033 出生年 (15分)(解题报告)
  7. 下图所示的PCB(进程控制块)的组织方式是(),图中()。【最全!最详细分析】
  8. 判断一个数是否是素数,为什么只要除到根号那个数就够了
  9. 12行代码AC——例题6-6 小球下落(Droppint Balls, UVa 679)——解题报告
  10. 这代码她不美吗?——试题 基础练习 十六进制转八进制