Android:这是一份全面 & 详细的 - 热修复 - 学习指南 (1),统统给你解决
示意图
2.2 Android 类加载机制(ClassLoader)简介
加载流程说明
示意图
注:若 2 个 Dex 文件中有重复的类,当加载时,则优先加载排序较前的 Dex 文件的类
若所需加载类 = class3,则最终加载的是排序较前的 Dex1 文件中的 class3
源码分析由于 具体实现类 PathClassLoader、DexClassLoader 都继承自 BaseDexClassLoader 类,所以此处主要讲解 BaseDexClassLoader 类中与类加载的相关方法 findClass()
/**
加载流程说明**/// 1. 传入需加载类的名字(classname)// 2. 通过 Dex 文件,寻找到所需类(findClass)// a. 按顺序遍历 ClassLoader 的所有 Dex 文件,即 集合 dexElements// b. 每遍历到 1 个 Dex 文件,则在该 Dex 文件中寻找所需加载的类// c. 若在该 Dex 文件找到该类,则返回;若找不到,则继续遍历下 1 个 Dex 文件// 3. 加载所需类
/**
BaseDexClassLoader 的 findClass()源码分析**/@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {
// 从 pathList 对象对象中寻找->>分析 1Class clazz = pathList.findClass(name);
if (clazz == null) {throw new ClassNotFoundException(name);}
return clazz;}
/**
分析 1:DexPathList 的 findClass()源码分析**/public Class findClass(String name) {// 1. 按顺序遍历 ClassLoader 的所有 Dex 文件,即 集合 dexElementsfor (Element element : dexElements) {DexFile dex = element.dexFile;
// 2. 每遍历到 1 个 Dex 文件,则在该 Dex 文件中寻找所需加载的类 ->>分析 2if (dex != null) {Class clazz = dex.loadClassBinaryName(name, definingContext);// 3. 若在该 Dex 文件找到该类,则返回;若找不到,则继续遍历下 1 个 Dex 文件 if (clazz != null) {return clazz;}}}
return null;}
/**
分析 2:DexFile 的 loadClassBinaryName()源码分析**/public Class loadClassBinaryName(String name, ClassLoader loader) {return defineClass(name, loader, mCookie);}
/**
分析 3:DexFile 的 defineClass()源码分析**/
private native static Class defineClass(String name, ClassLoader loader, int cookie);
#####3. 热修复 原理 3.1 具体描述把需修复、含 Bug 的类 独立打包到 1 个 Dex 文件中(记为:patch.dex)
评论