Qzone 超级补丁热修复方案原理

本文详细介绍了Qzone超级补丁热修复方案,基于dex分包,利用类加载机制中的双亲委托模式。在修复bug时,将修复后的类放入单独dex并插入到加载顺序前端。通过分析类加载流程,探讨了Dalvik下防止“unexpected DEX”异常的方法,包括构造函数插入代码以避免类被打上CLASS_ISPREVERIFIED标志。Qzone方案优点包括输出产物小、灵活性高,但存在不支持即时生效、启动耗时增加等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

Qzone 超级补丁技术基于dex分包方案,使用了多dex加载(multidex)的原理,大致的过程就是:把BUG方法修复以后,放到一个单独的dex文件,然后插入到dexElements数组的最前面,让虚拟机去加载修复完后的方法。

该方案的灵感来源?
没错就是类加载机制,相信大部分同学都对它有所了解吧。

ClassLoader 类加载机制

Android应用程序本质上使用的是java开发,使用标准的java编译器编译出Class文件,和普通的java开发不同的地方是把class文件再重新打包成dex类型的文件,这种重新打包会对Class文件内部的各种函数表、变量表等进行优化,最终产生了odex文件。odex文件是一种经过android打包工具优化后的Class文件,因此加载这样特殊的Class文件就需要特殊的类装载器,所以android中提供了DexClassLoader类。

类图:
clipboard_mh1534131797938.jpg

Android使用的是Dalvik虚拟机装载class文件,所以classloader不同于java默认类库rt.jar包中java.lang.ClassLoader, 可以看到android中的classloader做了些修改,但是原理还是差不多的。
学过java的同学都知道, 类加载器是采用双亲委派机制来进行类加载的。

双亲委托模式是什么?

某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

为什么要用双亲委托模式?
  1. 可以避免重复加载,当父加载器已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
  2. 安全性考虑,防止核心API库被随意篡改。我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中的定义类型,这样会存在非常大的安全隐患。

双亲委派机制 从ClassLoader.java 源代码可以清晰的看出来:
ClassLoader.java
classloader.png
流程大概如下:
1.判断类是否已经加载过;
2.父类加载器优先加载;
3.parent为null,则调用BootstrapClassLoader进行加载 ;
4.如果class依旧没有找到,则调用当前类加载器的findClass方法进行加载;

BaseDexClassLoader.java
baseDexClassLoader.png

DexPathList.java
dexpathllist.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值