一、热修复技术作用

  线上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的更多相关文章

  1. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  2. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  3. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  4. Android热更新开源项目Tinker集成实践总结

    前言 最近项目集成了Tinker,开始认为集成会比较简单,但是在实际操作的过程中还是遇到了一些问题,本文就会介绍在集成过程大家基本会遇到的主要问题. 考虑一:后台的选取 目前后台功能可以通过三种方式实 ...

  5. 微信开源的Android热补丁框架 Tinker

    前不久,微信开源了其Android热补丁框架Tinker,它的特别之处在于放在github.com/Tencent下面,是该账号下第一个正式的开源项目,可以看到腾讯对它的重视和认可. 早在6月份微信客 ...

  6. Android热修复技术原理详解(最新最全版本)

    本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结   通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...

  7. Android热修复技术原理详解

    阿里Dexposed -- native解决方案 原理: 直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能   他的思想完全来源于Xposed框架,完美诠释 ...

  8. 深入探索Android热修复技术原理读书笔记 —— 热修复技术介绍

    1.1 什么是热修复 对于广大的移动开发者而言,发版更新是最为寻常不过的事了.然而,如果你 发现刚发出去的包有紧急的BUG需要修复,那你就必须需要经过下面这样的流程: 这就是传统的更新流程,步骤十分繁 ...

  9. 全面了解Android热修复技术

    WeTest 导读 本文探讨了Android热修复技术的发展脉络,现状及其未来. 热修复技术概述 热修复技术在近年来飞速发展,尤其是在InstantRun方案推出之后,各种热修复技术竞相涌现.国内大部 ...

随机推荐

  1. java方法笔记: split,instanceof,StringBuilder(),append(),string ,Integer,Math,正则表达式

    http://swiftlet.net/archives/709 如果分隔符在前方,会显示“”,在尾部不显示: *|做分割,需要加\\ API文档如下 1.instanceof 查看前者是否是后者的实 ...

  2. (叉乘求面积) nyoj1011-So Easy[II]

    1011-So Easy[II] 内存限制:64MB 时间限制:1000ms 特判: No通过数:2 提交数:4 难度:2 题目描述: 这是一道基础的计算几何问题(其实这不提示大家也都看的出).问题描 ...

  3. (栈)leetcode 946. Validate Stack Sequences

    Given two sequences pushed and popped with distinct values, return true if and only if this could ha ...

  4. RS485 / RS422

    RS422可以变为RS485:A和Y短路(然后接T/R+),B和Z短路(然后接T/R-) RS485是半双工,只有两根线通信线,要么接收状态,要么发送状态 RE为低电平,作为接收器 DE为高电平,作为 ...

  5. php中加密和解密

    项目要和第三方进行接口对接,所以数据的安全很重要.第一次自己设计并实现,学习记录下 网上查了很多资料,真的很深奥 对称加密: 双方共用一个约定好的密钥进行数据的加密和解密,但是当密匙丢失,数据将有泄露 ...

  6. CodeForces160D 最小生成树 + dfs

    https://cn.vjudge.net/problem/26727/origin 题目大意: 给一个带权的无向图,保证没有自环和重边. 由于最小生成树不唯一,因此你需要确定每一条边是以下三种情况哪 ...

  7. Event Recommendation Engine Challenge分步解析第六步

    一.请知晓 本文是基于: Event Recommendation Engine Challenge分步解析第一步 Event Recommendation Engine Challenge分步解析第 ...

  8. JAVA入门教程 - idea 新建maven spring MVC项目

    用的是Idea2017版本.其他大同小异 1.新建项目 2.勾选Create from archetype 选中maven-archetype-webapp 3.输入项目名字. 4.下一步 5.点Fi ...

  9. KMP算法的next[]数组 的求法

    例如: next数组的求解方法是:第一位的next值为0,第二位的next值为1,后面求解每一位的next值时,根据前一位进行比较.首先将前一位与其next值对应的内容进行比较,如果相等,则该位的ne ...

  10. 理解self与this

    刚开始学习Python的类写法的时候觉得很是麻烦,为什么定义时需要而调用时又不需要,为什么不能内部简化从而减少我们敲击键盘的次数?你看完这篇文章后就会明白所有的疑问. self代表类的实例,而非类. ...