插件修复数据_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. 那在选择热修复方案时考虑点有哪些?
- 热更项目的需求
- 只需要简单的方法级别 Bug 修复?
- 需要资源及 so 库的修复?
- 需要 Native 的修复?
- 对平台兼容性要求及成功率要求?
- 是否需要对补丁包进行管理?
- 公司资源是否支持商业付费?
- 学习及使用成本
- 集成难度和复杂度
- 代码侵入性
- 调试维护
- 选择框架的关注点
- 尽量大厂
- 性能过关
- 有专人维护
- 热度高,开源社区活跃
2. 总结出需要热更的 SDK 特点
- 主要是代码热更,无so库、资源更新需求;
- 实时性要求高,因为一旦出问题,对业务方的影响极大;
- 兼容性要求高,你无法预料到业务方的活跃用户都有啥机型。
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. 数据分析
上线后我们最关心的就是补丁的兼容性和成功率。
- 补丁拉取成功率 = 请求补丁成功的用户 / 发起请求补丁的用户
- 补丁下载成功率 = 下载补丁成功的用户 / 尝试下载补丁的用户
- patch应用成功率 = patch成功的用户 - 回滚的用户 / 补丁下载成功的用户
3. 补丁回滚机制
我们需要支持自动监控崩溃,如果是下发的补丁引起的,则下次启动补丁自动失效,避免扩大影响范围。
以上这些思考,我将会在下篇博文中一一实现,敬请关注!
本篇完成耗时 6 个番茄钟(180 分钟)
我是 FeelsChaotic,一个写得了代码 p 得了图,剪得了视频画得了画的程序媛,致力于追求代码优雅、架构设计和 T 型成长。
欢迎关注 FeelsChaotic 的简书和掘金,如果我的文章对你哪怕有一点点帮助,欢迎 ❤️!你的鼓励是我写作的最大动力!
最最重要的,请给出你的建议或意见,有错误请多多指正!
插件修复数据_APP 热修复都懂了,你会 SDK 热修复吗?最全方案在这里!相关推荐
- 走嵌入式方向,一定要软硬件都懂吗?
知乎上看到这么一个问题:走嵌入式方向,一定要软硬件都懂吗? 如下写点个人看法,全文约2432个字,阅读时间约10分钟,仅供参考-- 一 信息时代知识爆炸 从以瓦特发明蒸汽机为代表的第一次工业革命,到 ...
- 华为 AI 芯片诞生;马云重当中国首富;微软修复数据删除 Bug | 极客头条
「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有料的新闻资讯,让所有技术人,时刻紧跟业界潮流. 快讯速知 华 ...
- 有了这个数据强一致“利器”,DBA们轻松修复数据对加班“say no”
本文分享自华为云社区<HDC.Cloud2021|华为云GaussDB让开发者们不再加班修复数据>,原文作者:心机胖. 众所周知,智能时代的来临正是因为开发者们用一行行代码铸就了千行百业向 ...
- 北京华客服务器数据恢复中心怎么样,北京修复数据
北京修复数据 2021-05-07 移动硬盘数据修复服务器硬盘离线数据丢失如何恢复?最近接手了一个服务器硬盘的数据恢复案例.用户带的服务器是IBM服务器,有四个windows操作系统的硬盘.服务器硬盘 ...
- sd卡数据恢复:sd卡损坏这样修复数据
sd卡损坏如何修复数据?很多数据存储设备使用久了之后,都容易出现损坏的情况,从而导致里面的数据丢失.乱码,大家都知道怎么修复受损的sd卡吗?丢失的数据又该如何恢复呢?下面就一起来了解下. 首先我们可以 ...
- HBase 2.0之修复工具HBCK2,修复数据
1.起因 此次修复数据情况是:服务器中毒导致HBASE异常关闭, 启动各种错误,实在没搞懂就清理了ZK关于HBASE的目录(rmr /hbase 建议先看原因,实在不行在做这个删除ZK操作,不对任何人 ...
- mysql数据库检表_MYSQL数据库检查数据表和修复数据表
数据库在运行中,会因为人为因素或一些不可抗力因素造成数据损坏.所以为了保护数据的安全和最小停机时间,我们需制定详细的备份/恢复计划,并定期对计划的有效性进行测试. 结合MySQL服务器的运行机制和所提 ...
- oracle模块损坏,Oracle中模拟及修复数据块损坏
Oracle中模拟及修复数据块损坏,itpub link: http://www.itpub.net/showthread.php?threadid=201766[@more@]Oracle中模拟及修 ...
- Android热更新十:自己写一个Android热修复
很早之前就想深入的研究和学习一下热修复,由于时间的原因一直拖着,现在才执笔弄起来. Android而更新系列: Android热更新一:JAVA的类加载机制 Android热更新二:理解Java反射 ...
最新文章
- 研三学生举报导师强迫学生延期毕业,事件再三反转,学校回应了!
- python线性表顺序存储实现_数据结构——基于C的线性表的顺序存储结构的基本操作的实现...
- 万网 php session,Session
- 漏洞战争软件漏洞分析精要 学习笔记
- 理解 | 理解a: float=10
- 记一次 .NET 某消防物联网 后台服务 内存泄漏分析
- php 留言板分页显示,php有分页的留言板,留言成功后怎么返回当前页?
- 西方餐厅的顶级食材,被中国人干到了“白菜价”
- Docker教程(一) Docker入门教程
- MTK 驱动开发(24)---camera模块的制作
- Xmind快捷键笔记
- 利用CEF山寨一个翻译器
- python 爬取妹子图
- myBatis --(3)数据的增删改查
- thinkphp出现此页面不能重定向
- iPhone如何截长图?iPhone长截图教程
- 72分辨率下1厘米等于多少像素,300分辨率下1厘米等于多少像素
- C语言基础知识入门和C语言入门基础知识大全
- docker-compose设置redis密码
- 人工智能/机器学习/深度学习:学习路线图
热门文章
- CentOS下ZooKeeper单机模式、集群模式安装
- android 蒙版图片带拖动_Android实现蒙版弹出框效果
- Spring Cloud Config入门(本地配置)
- 《大数据日知录:架构与算法》前言
- 【最全解析】1050 螺旋矩阵 (25分)
- C语言:L1-033 出生年 (15分)(解题报告)
- 下图所示的PCB(进程控制块)的组织方式是(),图中()。【最全!最详细分析】
- 判断一个数是否是素数,为什么只要除到根号那个数就够了
- 12行代码AC——例题6-6 小球下落(Droppint Balls, UVa 679)——解题报告
- 这代码她不美吗?——试题 基础练习 十六进制转八进制