Android热修复框架汇总整理(Hotfix)
Android平台出现了一些优秀的热更新方案,主要可以分为两类:一类是基于multidex的热更新框架,包括Nuwa、Tinker等;另一类就是native hook方案,如阿里开源的Andfix和Dexposed。
- 基于native hook的方案
需要针对dalvik虚拟机和art虚拟机做适配,需要考虑指令集的兼容问题,需要native代码支持,兼容性上会有一定的影响;
- 基于Multidex的方案
需要反射更改DexElements,改变Dex的加载顺序,这使得patch需要在下次启动时才能生效,实时性就受到了影响,同时这种方案在android N [speed-profile]编译模式下可能会有问题。
从技术流派上来说,Android热补丁技术应该分为以下两个流派:
- Native,代表有阿里的Dexposed、AndFix与腾讯的内部方案KKFix(查不到);
- Java,代表有Qzone的超级补丁、大众点评的Nuwa、百度金融的RocooFix, 饿了么的Amigo以及美团的Robust。
相关技术文章
Android 热修复专题:支付宝、淘宝、微信、QQ空间、饿了么、美丽说蘑菇街、美团大众点评方案集 https://zhuanlan.zhihu.com/p/25863920
阿里Dexposed -- native解决方案
原理:
直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能
他的思想完全来源于Xposed框架,完美诠释了AOP编程,这里用到最核心的知识点就是在native层获取到指定方法的结构体,然后改变他的nativeFunc字段值,而这个值就是可以指定这个方法对应的native函数指针,所以先从Java层跳到native层,改变指定方法的nativeFunc值,然后在改变之后的函数中调用Java层的回调即可。实现了方法的拦截功能。
- 基于开源框架Xposed实现,是一种AOP解决方案
- 只Hook App本身的进程,不需要Root权限
优点:
- 即时生效
- 不需要任何编译器的插桩或者代码改写,对正常运行不引入任何性能开销。这是AspectJ之类的框架没法比拟的优势;
- 对所改写方法的性能开销也极低(微秒级),基本可以忽略不计;
- 从工程的角度来看,热补丁仅仅是牛刀小试,它真正的威力在于『线上调试』;
- 基于Xposed原理实现的AOP不仅可以hook自己的代码,还可以hook同进程的Android SDK代码,这也就可以让我们有能力在App中填上Google自己挖的坑。
缺点:
- Dalvik上近乎完美,不支持ART(需要另外的实现方式),所以5.0以上不能用了;
- 最大挑战在于稳定性与兼容性,而且native异常排查难度更高;
- 由于无法增加变量与类等限制,无法做到功能发布级别;
相关链接:
- 文章:https://www.zhihu.com/question/31894163
- 文章:
http://www.wjdiankong.cn/android%E4%B8%AD%E5%85%8Droot%E5%AE%9E%E7%8E%B0hook%E7%9A%84dexposed%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0/ - Dexposed源码:https://github.com/alibaba/dexposed
- Xposed源码:https://github.com/rovo89/Xposed
阿里AndFix -- native解决方案
原理:
- 与Dexposed一样都基于开源框架Xposed实现,是一种AOP解决方案
优点:
- 即时生效
- 支持dalvik和art(AndFix supports Android version from 2.3 to 7.0, both ARM and X86 architecture, both Dalvik and ART runtime, both 32bit and 64bit.)
- 与Dexposed框架相比AndFix框架更加轻便好用,在进行热修复的过程中更加方便了
缺点:
- 面临稳定性与兼容性问题
- AndFix不支持新增方法,新增类,新增field等
相关链接:
QQ空间--Dex分包方案(大众点评的Nuwa参考其实现并开源)
原理:
- 原理是Hook了ClassLoader.pathList.dexElements[]。因为ClassLoader的findClass是通过遍历dexElements[]中的dex来寻找类的。当然为了支持4.x的机型,需要打包的时候进行插桩。
- 越靠前的Dex优先被系统使用,基于类级别的修复
优点:
- 不需要考虑对dalvik虚拟机和art虚拟机做适配
- 代码是非侵入式的,对apk体积影响不大
缺点:
- 需要下次启动才会生效
- 最大挑战在于性能,即Dalvik平台存在插桩导致的性能损耗,Art平台由于地址偏移问题导致补丁包可能过大的问题
- 虚拟机在安装期间为类打上CLASS_ISPREVERIFIED标志是为了提高性能的,我们强制防止类被打上标志是否会影响性能?这里我们会做一下更加详细的性能测试.但是在大项目中拆分dex的问题已经比较严重,很多类都没有被打上这个标志。
相关链接:
- 文章:https://zhuanlan.zhihu.com/magilu/20308548
- 文章:http://blog.csdn.net/sbsujjbcy/article/details/50812674
- Nuwa源码:https://github.com/jasonross/Nuwa
- HotFix源码:https://github.com/dodola/HotFix
- DroidFix源码:https://github.com/bunnyblue/DroidFix
美团Robust -- Instant Run 热插拔原理
原理:
- Robust插件对每个产品代码的每个函数都在编译打包阶段自动的插入了一段代码,插入过程对业务开发是完全透明
- 编译打包阶段自动为每个class都增加了一个类型为ChangeQuickRedirect的静态成员,而在每个方法前都插入了使用changeQuickRedirect相关的逻辑,当 changeQuickRedirect不为null时,可能会执行到accessDispatch从而替换掉之前老的逻辑,达到fix的目的。
优点:
- 几乎不会影响性能(方法调用,冷启动)
- 支持Android2.3-8.x版本
- 高兼容性(Robust只是在正常的使用DexClassLoader)、高稳定性,修复成功率高达99.9%
- 补丁实时生效,不需要重新启动
- 支持方法级别的修复,包括静态方法
- 支持增加方法和类
- 支持ProGuard的混淆、内联、优化等操作
缺点:
- 代码是侵入式的,会在原有的类中加入相关代码
- so和资源的替换暂时不支持
- 会增大apk的体积,平均一个函数会比原来增加17.47个字节,10万个函数会增加1.67M。
- 会增加少量方法数,使用了Robust插件后,原来能被ProGuard内联的函数不能被内联了
相关链接:
- 美团技术文章:https://tech.meituan.com/android_robust.html
- 美团技术文章:https://tech.meituan.com/android_autopatch.html
- Robust源码:https://github.com/Meituan-Dianping/Robust
微信Tinker
原理:
- 服务端做dex差量,将差量包下发到客户端,在ART模式的机型上本地跟原apk中的classes.dex做merge,merge成为一个新的merge.dex后将merge.dex插入pathClassLoader的dexElement,原理类同Q-Zone,为了实现差量包的最小化,Tinker自研了DexDiff/DexMerge算法。Tinker还支持资源和So包的更新,原理类同InstantRun
优点:
- 支持动态下发代码
- 支持替换So库以及资源
缺点:
- 不能即时生效,需要下次启动
微信已知问题:
- Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件(1.9.0支持新增非export的Activity);
- 由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
- 在Android N上,补丁对应用启动时间有轻微的影响;
- 不支持部分三星android-21机型,加载补丁时会主动抛出"TinkerRuntimeException:checkDexInstall failed";
- 对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标。
相关链接:
对比图(来自不同的地方)
来自微信
来自蘑菇街 Android 热修复探索之路
其他文章
浅谈Android热修复:
http://blog.csdn.net/caihongdao123/article/details/52051799
Android热修复框架汇总整理(Hotfix)的更多相关文章
- 手把手带你打造一个 Android 热修复框架
本文来自网易云社区 作者:王晨彦 Application 处理 上面我们已经对所有 class 文件插入了 Hack 的引用,而插入 dex 是在 Application 中,Application ...
- 手把手带你打造一个 Android 热修复框架(上篇)
本文来自网易云社区 作者:王晨彦 前言 热修复和插件化是目前 Android 领域很火热的两门技术,也是 Android 开发工程师必备的技能. 目前比较流行的热修复方案有微信的 Tinker,手淘的 ...
- [Android]热修复框架AndFix测试说明
AndFix,全称是Android hot-fix.是阿里开源的一个热补丁框架,允许APP在不重新发布版本的情况下修复线上的bug.支持Android 2.3 到 6.0,并且支持arm 与 X86系 ...
- Android热修复之AndFix使用教程
AndFix的github地址 AndFix 全称Android hot-fix,是alibaba的Android热修复框架,支持Android 2.3到6.0的版本,支持arm与X86系统架构,支持 ...
- Android热修复之微信Tinker使用初探
文章地址:Android热修复之微信Tinker使用初探 前几天,万众期待的微信团队的Android热修复框架tinker终于在GitHub上开源了. 地址:https://github.com/ ...
- Android热修复原理(一)热修复框架对比和代码修复
在Android应用开发中,热修复技术被越来越多的开发者所使用,也出现了很多热修复框架,比如:AndFix.Tinker.Dexposed和Nuwa等等.如果只是会这些热修复框架的使用那意义并不大,我 ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- 阿里SopHix热修复框架
2015年以来,Android开发领域里对热修复技术的讨论和分享越来越多,同时也出现了一些不同的解决方案,如QQ空间补丁方案.阿里AndFix以及微信Tinker(Bugly sdk也集成Tikner ...
- Android热修复技术总结
https://blog.csdn.net/xiangzhihong8/article/details/77718004 插件化和热修复技术是Android开发中比较高级的知识点,是中级开发人员通向高 ...
随机推荐
- Linux:快速找到占用CPU过高的Thread
1.通过top命令找到高耗CPU的进程,记下PID 2.使用命令ps -mp PID -o THREAD,tid,time找到高耗CPU的那些线程 3.jstack PID 4.对每个高耗CPU的线程 ...
- mybatis 基础
前言 MyBatis作为一款持久层的框架,从最初的ibatis更名,经过五六年的发展更新,如今已经更新到了3.4.5版本.MyBatis通过简单的xml或注解配置,就能将接口和Java的对象映射成数据 ...
- C# Lock、Monitor避免死锁
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- mvc中signalr实现一对一的聊天
Asp.net MVC中实现即时通讯聊天的功能.前几天刚写了一片基础入门的教程,今天就来实现一下使用signaIr实现一对一的聊天的功能,对于这种场景也是即时通讯最基本功能.好吧废话不多说.先来看一下 ...
- TXDragon的大火题合集
还有三个题没写,弃疗了 Solution
- [知了堂学习笔记]_用JS制作《飞机大作战》游戏_第1讲(素材查找和界面框架搭建)
一.查找素材: 二.分析游戏界面框架: 登录界面.游戏界面.暂停游戏界面.玩家死亡后弹出界面:并对应的界面包含什么元素: 三.分别搭建以上四个界面: 1.登录界面与游戏界面框架(隐藏游戏界面,四个界面 ...
- Mysql5.7.20使用group by查询(select *)时出现错误--修改sql mode
使用select * from 表 group by 字段 时报错 错误信息说明: 1055 - Expression #1 of SELECT list is not in GROUP BY cla ...
- hashlib 简单加密
import hashlib def md5(arg):#这是加密函数 md5_pwd = hashlib.md5(bytes('meac',encoding='utf-8')) md5_pwd.up ...
- 来一轮带注释的demo,彻底搞懂javascript中的replace函数
javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...
- Spring3.x企业开发应用实战读书笔记 —— 第三章IoC容器概述
声明: 本篇博客绝大多数内容为<Spring3.x企业开发应用实战>一书原内容,所有版权归原书作者所有!,仅供学习参考,勿作他用! 3.2 相关Java基础知识 Java语言允许通过 ...