Android热更新技术——Tinker、nuwa、AndFix、Dexposed
一、热修复技术作用
线上app BUG紧急修复,不重新发版,不重新安装,在线远程修复问题
二、局限性与适用场景
- 补丁只能针对单一客户端版本,随着版本差异变大补丁体积也会增大;
- 补丁不能支持所有的修改,例如AndroidManifest;
- 补丁无论对代码还是资源的更新成功率都无法达到100%。
既然补丁技术无法完全代替升级,那它适合使用在哪些场景呢?
1.轻量而快速的升级
2.远端调试
3.数据统计
4.其他(Instant Run)
Android官方也使用热补丁技术实现Instant Run。它分为Hot Swap、Warm Swap与Cold Swap三种方式。
三、热修复的原理
1、通过更改dex加载顺序实现热修复(下载补丁后app需要重启,而后才会加载补丁生效)
通过更改含有bug的dex文件的加载顺序;在dex的加载中,若已找到方法则不会继续查找,所以如果能让修复之后的方法在含有bug的方法之前加载就能达到修复bug的目的。把有问题的类修复后,放到一个单独的dex,通过反射插入到dexElements数组的最前面,让虚拟机优先加载打完补丁的class。
实践中,会发现运行加载类的时候报preverified错误,原来在DexPrepare.cpp,将dex转化成odex的过程中,会在DexVerify.cpp进行校验,验证直接引用的类和clazz是否在同一个dex,如果是,则会打上CLASS_ISPREVERIFIED标志。通过在所有类(Application除外,当时还没加载自定义类的代码)的构造函数插入一个对在单独的dex的类的引用,就可以解决这个问题。空间使用了javaassist进行编译时字节码插入。
隐患:虚拟机在安装期间为类打上CLASS_ISPREVERIFIED标志是为了提高性能的,我们强制防止类被打上标志多少会影响app的性能。但是在大项目中拆分dex的问题已经比较严重,很多类都没有被打上这个标志。
开源实现有Nuwa, HotFix, DroidFix。实际应用案例:QQ空间
2、通过Native替换方法指针的方式实现热修复(下载补丁后app不需要重启,即可加载补丁生效)
主要是阿里开源的两个热修复框架:Dexpost AndFix。它们都是通过Native层使用指针替换的方法替换bug,达到修复bug的目的,具体可参考其github文章。
(1)基于Xposed的AOP框架,方法级粒度,可以进行AOP编程、插桩、热补丁、SDK hook等功能。
Xposed需要Root权限,是因为它要修改其他应用、系统的行为,而对单个应用来说,其实不需要root。 Xposed通过修改Android Dalvik运行时的Zygote进程,并使用Xposed Bridge来hook方法并注入自己的代码,实现非侵入式的runtime修改。
我们知道,应用启动的时候,都会fork zygote进程,装载class和invoke各种初始化方法,Xposed就是在这个过程中,替换了app_process,hook了各种入口级方法(比如handleBindApplication、ServerThread、ActivityThread、ApplicationPackageManager的getResourcesForApplication等),加载XposedBridge.jar提供动态hook基础。
方法级的替换是指,可以在方法前、方法后插入代码,或者直接替换方法。只能针对java方法做拦截,不支持C的方法。
硬伤是不支持art,不支持art,不支持art。
(2)AndFix同样是方法的hook,AndFix不像Dexposed从Method入手,而是以Field为切入点。dalvik和art都支持
使用上,直接写一个新的类,会由补丁工具会生成注解,描述其与要打补丁的类和方法的对应关系。
3、微信热补丁方案(下载补丁后app需要重启,而后才会加载补丁生效)
思想是全量替换新的Dex。即完全使用新的Dex,这样既不出现Art地址错乱的问题,在Dalvik也无须插桩。考虑到补丁包的体积,不能直接将新的Dex放在里面。但可以将新旧两个Dex的差异放到补丁包中,最简单可以采用BsDiff算法。
简单来说,在编译时通过新旧两个Dex生成差异path.dex。在运行时,将差异patch.dex重新跟原始安装包的旧Dex还原为新的Dex。这个过程可能比较耗费时间与内存,所以我们是单独放在一个后台进程:patch中。为了补丁包尽量的小,微信自研了DexDiff算法,它深度利用Dex的格式来减少差异的大小。它的粒度是Dex格式的每一项,可以充分利用原本Dex的信息,而BsDiff的粒度是文件,AndFix/QZone的粒度为class。
在最极端的情况,由于利用了原本dex的信息完全替换一个13M的Dex,我们的补丁大小也仅仅只有6.6M。
但是这套方案并非没有缺点,它带来的问题有两个:
(1)占用Rom体积;这边大约是你修改Dex数量的1.5倍(dexopt与dex压缩成jar)的大小。
(2)一个额外的合成过程;虽然我们单独放在一个进程上处理,但是合成时间的长短与内存消耗也会影响最终的成功率。
微信的热补丁方案叫做Tinker,也算缅怀一下Dota中的地精修补匠,希望能做到无限刷新。
若不care性能损耗与补丁包大小,QZone方案是最简单且成功率最高的方案(没有单独的合成过程)。相对Tinker来说,它的占用Rom体积也更小。另一方面,QZone与Tinker的成功率大约相差3%左右。
事实上,一个完整的框架应该也是一个容易使用的框架。Tinker对补丁版本管理、进程管理、安全校验等都有着很好的支持。同时我们也支持gradle与命名行两种接入方式。希望在不久的将来,它可以很快的跟大家见面。
https://www.cnblogs.com/aademeng/articles/6883861.html
http://www.bbs0101.com/archives/1437.html(讲解和总结的很好,包含是否需要重启)
https://www.jianshu.com/p/52cacc0f23fa
https://www.cnblogs.com/fanfu1/p/5506149.html
Android热更新技术——Tinker、nuwa、AndFix、Dexposed的更多相关文章
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- Android热更新开源项目Tinker集成实践总结
前言 最近项目集成了Tinker,开始认为集成会比较简单,但是在实际操作的过程中还是遇到了一些问题,本文就会介绍在集成过程大家基本会遇到的主要问题. 考虑一:后台的选取 目前后台功能可以通过三种方式实 ...
- 微信开源的Android热补丁框架 Tinker
前不久,微信开源了其Android热补丁框架Tinker,它的特别之处在于放在github.com/Tencent下面,是该账号下第一个正式的开源项目,可以看到腾讯对它的重视和认可. 早在6月份微信客 ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- Android热修复技术原理详解
阿里Dexposed -- native解决方案 原理: 直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能 他的思想完全来源于Xposed框架,完美诠释 ...
- 深入探索Android热修复技术原理读书笔记 —— 热修复技术介绍
1.1 什么是热修复 对于广大的移动开发者而言,发版更新是最为寻常不过的事了.然而,如果你 发现刚发出去的包有紧急的BUG需要修复,那你就必须需要经过下面这样的流程: 这就是传统的更新流程,步骤十分繁 ...
- 全面了解Android热修复技术
WeTest 导读 本文探讨了Android热修复技术的发展脉络,现状及其未来. 热修复技术概述 热修复技术在近年来飞速发展,尤其是在InstantRun方案推出之后,各种热修复技术竞相涌现.国内大部 ...
随机推荐
- appium desktop 1.7 byName不能用,重写
@Override public WebElement findElementByName(String name){ String string="new UiSelector().tex ...
- spring的设计模式
spring中用到哪些设计模式 1.工厂模式,这个很明显,在各种BeanFactory以及ApplicationContext创建中都用到了: 2.模版模式,这个也很明显,在各种BeanFacto ...
- qml:基本知识记录
1. property信号处理函数: 在qml中,通过property可以定义属性,这些属性自带信号处理函数,例如: property string szTitle: “hello wor ...
- 【优秀的设计绘图软件】Affinity Designer Beta for Mac 1.7
[简介] Affinity Designer 1.7 beta 中文版本,具有全新的UI界面和功能,支持最新的 macOS Mojave 10.14 系统,Affinity Designer是 ...
- python对象继承
继承允许我们在两个或者更多的类之间创建一种“是一个”的关系,这种关系把共同的细节抽象到一个超类里. 从技术上讲,每一个我们创建的类都使用了继承,所有的python类都是一个叫做object的特殊类的子 ...
- Vue less使用scope时渗入修改子组件样式
@deep: ~'>>>'; .wrap { @{deep} .component1 { width: 120px; } }
- ansible-playbook 单个yml文件部署tomcat简单示例
#单yaml配置[root@jenkins pb]# cat tomcat.yml --- - hosts: eee vars: #设置变量 war_files: /var/lib/jenkins/w ...
- IMDB影评倾向分类 - N-Gram
catalogue . 数据集 . 模型设计 . 训练 1. 数据集 0x1: IMDB影评数据 本数据库含有来自IMDB的25,000条影评,被标记为正面/负面两种评价 from keras.dat ...
- Hbase运维手册(1)
1. region情况 需要检查 1. region的数量(总数和每台regionserver上的region数) 2. region的大小 如果发现异常可以通过手动merge region和手动分配 ...
- 分享两个好用的nosql GUI工具
redis: 真是千呼万唤始出来,终于有了redis gui 谢谢作者,但中文乱码问题貌似还没有解决呀! https://github.com/caoxinyu/RedisClient mongoDB ...