Android热修复Java类_Android 热修复原理

Android 热修复

在Android的热修复中主要用来替换类,资源,so的过程;

Java 虚拟机

栈架构指令集的主要缺点是执行速度相对来说稍微慢一些;基于堆栈的机器需要更多指令,(内存)

Android 虚拟机

而基于寄存器(硬件在CPU内部)的机器指令更长

速度: CPU - > 寄存器 -> 内存 -> 外存

Android 目前有2中虚拟机, Dalvik 和 ART 虚拟机;

Android 虚拟机和编译加载顺序

Android 热修复其实主要是针对 Android 虚拟机加载类的一个过程,所以首先先我们应该知道 Android 常用的虚拟机是 Dalvik 虚拟和 ART 虚拟机;

Android 4.0 之前是主要是的 Dalvik 虚拟机。 Android 4.4 之后开始支持 ART 虚拟机(可选), Android 5.0 之后就是 ART 虚拟机;

Android 4.0 --> Android 4.4 --> Android 5.0 ---> Android 7.0

Dalvik 虚拟机在 Android 2.2 的时候引入了 JIT (Just in time), 也就是一边运行,一边编译成机器码在运行;这种编译成机器码的过程在应用重启的时候需要重新编译成机器码再运行,有点浪费性能(不是持久化),重复翻译,编译,运行;

在 Android 5.0 之后就使用完全使用 ART 虚拟机;因为在 AOT (ahead of time) 的操作在安装的时候把 dex 优化成odex; 在Android N (7) 之前是全量dex 优化成 odex, 这样导致安装 apk 的时候,或者系统更新重启的时候非常耗时,特别的慢;

所以在 Android N 后引入了 JIT 和 AOT 的混合模式; 可以理解为“全时段的编译”(All-Of-the-Time compilation, 也叫 AOT;是不是发现有2个 AOT, 一开始我也很懵逼的;其实和Android 5.0 中的 AOT 是不太一样的;还有要注意的是Android N 之后的 JIT 和 Davlik 虚拟机中的JIT是不一样的,简单理解就是高级版的JIT;这个高级版本的 JIT 过程会把处理后的odex缓存到 base.art (有些地方也叫 image ) 中;等下次app启动的时候,就先直接把这个优化后的 base.art 加载到内存中;这样就不会重复的 JIT了;

混合模式的理解

ART 初期是使用全量的 AOT (aheader of time) 变成机器码(指令); 因为耗安装时间和系统升级后的启动时间;所以在 ART 的时候,先把dex 解释成中间态的,不编译成机器码。在运行的时候,或者充电的时候,只编译“热代码”

Android N(7.x)开发者预览版包含了一个混合模式的运行时。应用在安装时不做编译,而是解释字节码,所以可以快速启动。ART中有一种新的、更快的解释器,通过一种新的JIT完成,但是这种JIT的信息不是持久化的。取而代之的是,代码在执行期间被分析,分析结果保存起来。然后,当设备空转和充电的时候,ART会执行针对“热代码”进行的基于分析的编译,其他代码不做编译。为了得到更优的代码,ART采用了几种技巧包括深度内联。

对同一个应用可以编译数次,或者找到变“热”的代码路径或者对已经编译的代码进行新的优化,这取决于分析器在随后的执行中的分析数据。这个步骤仍被简称为AOT,可以理解为“全时段的编译”(All-Of-the-Time compilation)。

源码类到机器执行的文件过程

主要过程: java - (dex, class) - opt/oat -- odex;

Davlik 虚拟机: java - dex - opt -- D 类型的 odex (优化过后的还是需要翻译); JIT

ART虚拟机: java -- dex -- oat -- A 类型的 odex (机器码类型文件); AOT ( Ahead of time)

混合模式: java -- dex -- oat -- (D类型的 odex, base.art: 热缓存,image) JIT(高级的JIT); AOT (All-Of-the-Time compilation)可以理解为“全时段的编译” ,profile

注意以上的 A 类型 odex 和 D 类型的 odex,只是用来代码 2 种是不同的 odex,便于理解;

补丁包

补丁包主要有 class, 资源文件,so的改动;

资源文件方案;替换 AssertManager, ---> 加载 resources.arsc

os 还不清楚,没研究过, 可能使用classLoader 加载放入so 目录

类 :底层替换和类加载器方案

本文主要诉说类加载器的方案;

类补丁生效原理

底层替换方案 (阿里系)AndFix,

类加器载方案 (腾讯系)QFix, tinker(粒度太细了), Sophix 使用类的替换(粒度大一点)

因为 Android 有 2 款虚拟机,所以应该针对 2 款虚拟机加载过程进行分析和处理;

Davlik 虚拟机的限制

Android 在编译的时候有个 65536 (2的16次方)问题。受限于Dlv 虚拟机的限制;不只是方法名有限制,其实字段也是有限制的;

Davlik Class resolved by unexpected DEX: 限制和处理方式

if (!fromUnverifiedConstant && // 条件3

IS_CLASS_FLAG_SET(referrer, CLASS_ISPREVERIFIED)) // 条件1

{

ClassObject* resClassCheck = resClass;

if (dvmIsArrayClass(resClassCheck))

resClassCheck = resClassCheck->elementClass;

if (referrer->pDvmDex != resClassCheck->pDvmDex &&

resClassCheck->classLoader != NULL) // 条件2

{

ALOGW("Class resolved by unexpected DEX:"

" %s(%p):%p ref [%s] %s(%p):%p",

referrer->descriptor, referrer->classLoader,

referrer->pDvmDex,

resClass->descriptor, resClassCheck->descriptor,

resClassCheck->classLoader, resClassCheck->pDvmDex);

ALOGW("(%s had used a different %s during pre-verification)",

referrer->descriptor, resClass->descriptor);

dvmThrowIllegalAccessError(

"Class ref in pre-verified class resolved to unexpected "

"implementation");

return NULL;

}

}

三个条件

CLASS_ISPREVERIFIED 这个标记被打上的原理是,只要一个类里面和这个类的依赖都在一个dex中,那么这些类就被打上 PREVERIFIED 的标记;

单独有个[特殊的.dex]这个 dex 里面只有一个类,且其他的dex中的类都引用一下这个单独 dex 里面的类,那么,项目中所有的类,就不会被打上 CLASS_ISPREVERIFIED 这个标记 dex 数组: [ 1.dex, 2.dex, 3.dex, 特殊的.dex(插桩类)]

referrer->pDvmDex != resClassCheck->pDvmDex

补丁类和引用类应该在同一个dex里面;

fromUnverifiedConstant hook 使用 native 方式

类加载器的双亲委派加载机制

类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载

相关日志

12-07 10:05:27.859 11471-11471/app.mj.com.ihour I/MyApp: getClassLoader() : dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/app.mj.com.ihour-2/base.apk"],nativeLibraryDirectories=[/data/app/app.mj.com.ihour-2/lib/arm64, /system/lib64, /vendor/lib64]]]

12-07 10:05:27.860 11471-11471/app.mj.com.ihour I/MyApp: getClassLoader().getParent(): java.lang.BootClassLoader@36e0624

12-07 10:05:27.860 11471-11471/app.mj.com.ihour I/MyApp: getClassLoader().getParent().p: null

参考文献

主要参考图

%E7%83%AD%E4%BF%AE%E5%A4%8D_%E5%AF%B9%E6%AF%94.jpeg

qq2.jpeg

qq.jpeg

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值