文章目录
Android 插件化系列文章目录
前言
一、通过反射获取 "插件包" 中的 Element[] dexElements
1、反射获取 BaseDexClassLoader.class
2、反射获取 DexPathList pathList 字段
3、反射获取 DexPathList pathList 对象
4、获取 DexPathList pathList 对象
5、反射获取 Element[] dexElements 字段
6、反射获取 Element[] dexElements 对象
二、完整代码示例
前言
在上一篇博客 【Android 插件化】Hook 插件化框架 ( hook 插件化原理 | 插件包管理 ) 中简要介绍了 hook 插件化原理 , 并开始开发插件化管理类 , 本博客中开始加载插件包中的 Element[] dexElements ;
Android 中的类加载器 DexClassLoader , PathClassLoader 的父类是 BaseDexClassLoader ,
BaseDexClassLoader 中有 private final DexPathList pathList 成员变量 ,
DexPathList 中有 private Element[] dexElements 成员变量 ,
Element[] dexElements 就是最终存放 Dex 字节码数据的内存变量 , 最终将 " 插件包 " 中读取的 dexElements 合并到 " 宿主 " 应用的 dexElements 中 ;
一、通过反射获取 “插件包” 中的 Element[] dexElements
反射 " 插件包 " 应用的 dexElement 执行步骤 :
① 反射获取 BaseDexClassLoader.class
② 反射获取 BaseDexClassLoader.calss 中的 private final DexPathList pathList 成员字段
③ 反射获取 plugin_dexClassLoader 类加载器中的 DexPathList pathList 成员对象
④ 获取 DexPathList.class
⑤ 反射获取 DexPathList.class 中的 private Element[] dexElements 成员变量的 Field 字段对象
⑥ 反射获取 DexPathList 对象中的 private Element[] dexElements 成员变量对象
1、反射获取 BaseDexClassLoader.class
反射获取 BaseDexClassLoader.class , 通过反射获取插件包中的 dexElements , 这种类加载是合并类加载 , 将所有的 Dex 文件 , 加入到应用的 dex 文件集合中 , 可参考 dex 加固 , 热修复 , 插装式插件化 的实现步骤 ;
反射出 BaseDexClassLoader 类 , PathClassLoader 和 DexClassLoader 都是 BaseDexClassLoader 的子类 ;
代码示例 :
// ① 反射获取 BaseDexClassLoader.class // 通过反射获取插件包中的 dexElements // 这种类加载是合并类加载 , 将所有的 Dex 文件 , 加入到应用的 dex 文件集合中 // 可参考 dex 加固 , 热修复 , 插装式插件化 的实现步骤 // 反射出 BaseDexClassLoader 类 , PathClassLoader 和 DexClassLoader // 都是 BaseDexClassLoader 的子类 // 参考 https://www.androidos.net.cn/android/9.0.0_r8/xref/libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java Class<?> baseDexClassLoaderClass = null; try { baseDexClassLoaderClass = Class.forName("dalvik.system.BaseDexClassLoader"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
2、反射获取 DexPathList pathList 字段
// ② 反射获取 BaseDexClassLoader.calss 中的 private final DexPathList pathList 成员字段 Field plugin_pathListField = null; try { plugin_pathListField = baseDexClassLoaderClass.getDeclaredField("pathList"); // 设置属性的可见性 plugin_pathListField.setAccessible(true); } catch (NoSuchFieldException e) { e.printStackTrace(); }
3、反射获取 DexPathList pathList 对象
根据 Field 字段获取 成员变量 , DexClassLoader 继承了 BaseDexClassLoader, 因此其内部肯定有 private final DexPathList pathList 成员变量 ;
// ③ 反射获取 plugin_dexClassLoader 类加载器中的 DexPathList pathList 成员对象 // 根据 Field 字段获取 成员变量 // DexClassLoader 继承了 BaseDexClassLoader, 因此其内部肯定有 // private final DexPathList pathList 成员变量 Object plugin_pathListObject = null; try { plugin_pathListObject = plugin_pathListField.get(plugin_dexClassLoader); } catch (IllegalAccessException e) { e.printStackTrace(); }