ClassLoader类加载的示例分析
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要介绍了ClassLoader类加载的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Java类加载器1、BootCl
千家信息网最后更新 2025年11月07日ClassLoader类加载的示例分析
这篇文章主要介绍了ClassLoader类加载的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
Java类加载器
1、BootClassLoader: 用于加载Android Framework层class文件。
2、PathClassLoader: 用于Android应用程序类加载器。可以加载指定的dex,jar、zip、zpk中的classes.dex
3、DexClassLoader:加载指定的dex,以及jar、zip、apk中的classes.dex

源码解析
1.ClassLoader中提供loadClass用于加载指定类
//ClassLoader.javapublic Class> loadClass(String name) throws ClassNotFoundException { //该处调用了两个参数的重载方法 return loadClass(name, false); } protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException { //先查一下该类是否已经加载过了 Class> c = findLoadedClass(name); if (c == null) { try { //双亲委托机制,先让爸爸去找 if (parent != null) { c = parent.loadClass(name, false); } else { //如果parent为null,则用BootClassLoader进行加载 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { //如果都找不到就自己去找,此方法在子类BaseDexClassLoader类中有重写 c = findClass(name); } } return c; }2.BaseDexClassLoader类中对findClass有重写,也是实际会使用执行的
//BaseDexClassLoader.java//查找class @Override protected Class> findClass(String name) throws ClassNotFoundException { ... //这里通过pathList变量来查找,而pathList是在BaseDexClassLoader的构造方法中初始化的 Class c = pathList.findClass(name, suppressedExceptions); ... return c; } private final DexPathList pathList;public BaseDexClassLoader(String dexPath, File optimizedDirectory, String librarySearchPath, ClassLoader parent, boolean isTrusted) { super(parent); //构造方法中初始化pathList变量 this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted); }3.BaseDexClassLoader中是通过调用DexPathList中的findClass来实现的,那么接下来我们分析一下DexPathList是怎么实现的
//DexPathList.java//是一个Element数组,一个element中包含一个 DexFile,DexFile就代表一个Dex文件,里面的native(C/C++)函数来进行Dex的加载工作 private Element[] dexElements; public Class> findClass(String name, Listsuppressed) { for (Element element : dexElements) { //此处调用Element的findClass来实现, Class> clazz = element.findClass(name, definingContext, suppressed); if (clazz != null) { return clazz; } } return null; }// Element为DexPathList的内部类static class Element { private final File path; //一个DexFile就代表一个Dex文件 private final DexFile dexFile; //有多个构造方法,但都仅是将值传过来,让Element来持有一个DexFile public Element(DexFile dexFile) { this.dexFile = dexFile; this.path = null; } public Class> findClass(String name, ClassLoader definingContext, List suppressed) { //通过DexFile来加载类 return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed) : null; } }DexPathList(ClassLoader definingContext, String dexPath, String librarySearchPath, File optimizedDirectory, boolean isTrusted) { //通过makeDexElements方法为dexElements初始化 this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions, definingContext, isTrusted);}//腾讯系的热修复,诸如微信tinker、qq空间qfix原理便是反射此方法,将修复后的类打包成dex,通过反射该方法来将文件转化为Element,并将新生成的element放到dexElements前面,这样下次系统再去寻找某个class时,会先从修复后的dex中来找class,找到后便不再继续查找,从而修复该class,此方式便为插桩private static Element[] makeDexElements(List files, File optimizedDirectory, List suppressedExceptions, ClassLoader loader, boolean isTrusted) { Element[] elements = new Element[files.size()]; ... for (File file : files) { if (name.endsWith(DEX_SUFFIX)) { //以 .dex 结尾的 // Raw dex file (not inside a zip/jar). //加载dex文件 dex = loadDexFile(file, optimizedDirectory, loader, elements); if (dex != null) { elements[elementsPos++] = new Element(dex, null); } } } ... return elements; }private static DexFile loadDexFile(File file, File optimizedDirectory, ClassLoader loader, Element[] elements) throws IOException { if (optimizedDirectory == null) { return new DexFile(file, loader, elements); } else { String optimizedPath = optimizedPathFor(file, optimizedDirectory); return DexFile.loadDex(file.getPath(), optimizedPath, 0, loader, elements); } }
4.这里通过 new DexFile 或者 loadDex方法来创建DexFile,两者类似,那我们拿new DexFile 来举例分析
//DexFile.javaprivate DexFile(String sourceName, String outputName, int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException { ... //此处调用openDexFile来实现 mCookie = openDexFile(sourceName, outputName, flags, loader, elements); ... }private static Object openDexFile(String sourceName, String outputName, int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException { //此处通过调用 openDexFileNative来实现 return openDexFileNative(new File(sourceName).getAbsolutePath(), (outputName == null) ? null : new File(outputName).getAbsolutePath(), flags, loader, elements); }//openDexFileNative是一个native方法,是由C/C++来实现的private static native Object openDexFileNative(String sourceName, String outputName, int flags, ClassLoader loader, DexPathList.Element[] elements);感谢你能够认真阅读完这篇文章,希望小编分享的"ClassLoader类加载的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
方法
文件
分析
篇文章
示例
代表
变量
此方法
反射
接下来
两个
价值
兴趣
函数
原理
参数
双亲
同时
多个
子类
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
计算机网络技术发展条件
做机房空调软件开发
数据库服务如何启动
软件开发工具的重要性能有
妇女联合会网络安全宣传
web服务器 书籍
证券公司数据库运维
vs内置数据库使用
饥荒服务器启动的原因
我的世界服务器的副本咋做
数据库磁盘空间使用率小于85%
湖北网络技术分类资费
狙佬服务器叫什么
服务器限制cpu主频
莆田童谣国家网络安全宣传周
项目开发如何控制嵌入式软件开发
食材配送软件开发
二次元捏脸软件开发
数据库技术在供应链里的应用
重庆银行软件开发岗
黄浦区品牌软件开发费用是多少
苏州智喵互联网络科技有限公司
上海联想分布式存储数据库
上海口袋云网络技术有限公司
证券公司数据库运维
mssql数据库事务
linux显示服务器什么意思
网吧用什么样的服务器
网银助手下载提示服务器没响应
网络技术发展方向论文