热修复技术(二)

1. 热修复解决方案

  热补丁方案有很多,比较有名是有腾讯Tinker、阿里的AndFix、美团的RoBust以及QZone的超级补丁方案。
在这里插入图片描述

2. AndFix热修复

  在native层动态替换java层的方法,通过native层hook java层的代码。
AndFix为什么能即时生效?
答:下次加载的时候会加载补丁包中的对应的方法,不会再调用原来有bug的方法。
在这里插入图片描述
在这里插入图片描述

3. Robust

  对每个函数都在编译打包阶段自动的插入了一段代码,类似于代理,将方法执行的代码重定向到其他方法中。

//编写的代码
@Modify  //改动代码后手动添加注解用于补丁包生成
public long getIndex() {
	return 100;
}

//经过插桩后时间执行的代码
public long getIndex() {
	if (changeQuickRedirect != null) {
		return  修复的实现;
	}
	return 100L;
}

4. Tinker

  Tinker通过计算对比指定的Bask Apk中的dex与修改后的Apk中的dex的区别,补丁包中的内容即为两者差分的描述。运行时将Base Apk中的dex与补丁包进行合成,重启后加载全新的合成后的dex文件。
在这里插入图片描述

5. Qzone

  Qzone与Tinker比较类似,与Tinker不同的是,Tinker是一个patch.dex差分包,并且需要下载下来进行合成一个类,而QZone就是一个完整修复的类,不需要合成。
在这里插入图片描述

6. ClassLoader

在这里插入图片描述

	public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
        super((String)null, (File)null, (String)null, (ClassLoader)null);
        throw new RuntimeException("Stub!");
    }

    public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) {
        super((String)null, (File)null, (String)null, (ClassLoader)null);
        throw new RuntimeException("Stub!");
    }

  • BootClassLoader
    用于加载Android Framework层class文件

  • PathClassLoader
    用于Android应用程序类加载器。可以加载指定的dex,以及jar、zip、apk中的classes.dex

  • DexClassLoader
    加载指定的dex,以及jar、zip、apk中的classes.dex

PathClassLoader与DexClassLoader的区别:只是DexClassLoader构造函数中多了一个参数optimizedDirectory,用于指定特定的路径(app私有路径/data/data/packageName)存放odex,即多了一个dexopt优化流程,对dex文件进行验证和优化为odex(Optimized dex)文件,而PathClassLoader存放odex是放在默认路径下/data/davlik-cache

ART会执行AOT,但针对Dalvik开发的应用也能在ART环境中运作

  • dexopt
    对dex文件进行验证和优化为odex(Optimized dex)文件
  • dexAot
    在安装时对dex文件执行dexopt优化之后再将odex进行AOT提前编译操作,编译为OAT可执行文件(机器码)。

7. 双亲委托机制

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

  • 避免重复加载,当父类加载器已经加载了该类的时候,就没有必要子ClassLoader再加载一次。

  • 安全性考虑,防止核心API库被随意篡改。

为什么要这样设计?
答:应用启动的就会创建BootClassLoader来加载framework中所有的类,而自己写的Activity代码BootClassLoader是没有办法加载的,它只能由PathClassLoader进行加载,因为自己写的Activity类它在apk中,而不在系统中。因此需要PathClassLoader来加载apk中的类。假如没有双亲委派机制,自己写的MainActivity需要继承AppCompatActivity(它属于framwork中的),framework中的类被BootClassLoad进行加载了,那PathClassLoader加载framework中的类就需要加载2次(apk中的类和framework中的类),其实framework中的类已经被BootClassLoad加载了,因此构成这样的一个双亲委派机制可以避免重复加载。

8. 类查找流程

在这里插入图片描述

9. 热修复流程

在这里插入图片描述

  • 获取到当前应用的PathClassloader;
  • 反射获取到DexPathList属性对象的pathList;
  • 反射修改pathList的dexElements
    1. 把补丁包patch.dex转化为Element[] (patch)
    2. 获得patchList的dexElements属性(old)
    3. patch + dexElements合并,并反射赋值给pathList的dexElements

dexElements是什么?
答:是一个Element数组,Element中包含一个DexFile
DexFile就代表一个Dex文件,里面的native(C/C++)函数来进行Dex的加载工作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值