BaseDexClassLoader 那些事
一,BaseDexClassLoader
是如何创建 DexElements 的?makeDexElements 的实现细节:
1.针对如何创建 DexElements 的,
BaseDexClassLoader 这个类有三种构造方法,只分析两个(因为另外一个只不过是其中一个的扩展,对于加载 DexElements 的方式并没有改变)。首先 parent 不能少,接下来的属性就是两种创建 DexElements 的不同方式,其中一个构造方法是传入 bytes 数组,另外两个是用的 dexFilePath(除此之外构造方法还需要很多参数,但对于这个问题是没有必要的)。传入的如果是 bytes 数组的话会调用 makeInMemoryDexElements,而如果是 dexPath 的话就是调用makeDexElements这个方法来创建 DexElements 的。
2.实现细节:
创建 ClassLoader 时会创建 DexElement 数组,也就是 Dex 数组。创建的时候都会创建一个异常类型的集合当加载 DexFile 出错的时候就会添加到这个集合中,构造方法执行完然后在读这个异常集合里面的数据进行保存到本地变量中。创建 Element 数组的情况根据 ClassLoader 的两个构造方法也会有两种情况:
如果是 dexPath 会进行对传入的 DexClassLoader 的文件目录进行解析成一个个 File 集合,然后调用 makeDexElements 创建 element 数组。

所以 Dex 即 Element 有这样三种情形被添加到 Element 数组中:
1、遍历到文件夹创建一个 Element,传入的参数为遍历的参数 File
2.遍历到文件,碰到的是以.dex 结尾的文件进行调用 loadDexFile 加载 DexFile 结构,如果不为空接着创建 Element 传入 DexFile 结构和一个 null(这个代表的是后缀为 dex 文件成功加载进内存)3.遍历到文件,但是不是以.dex 文件结尾的,依然调用 loadDexFile 加载 DexFile 结构,不管为不为空都创建一个 Element,但是空的话传入的参数为遍历的参数 File;不为空的话创建将 dexFile 属性传入并且在传入参数 File(这个代表的是不是.dex 后缀的文件成功加载到内存)。
综合分析:Element 有两个构造方法:第一个构造方法接受一个参数为解析后的 dex 文件的 File 对象第二个构造方法比第一个多了一个参数,第一个参数是 dexFile 对象,第二个属性和第一个构造方法一样
如果是 byte 数组的话,会手动进行创建 DexFile 区别于 dexPath 的利用 loadDexFile,这种情况下会直接创建 Element(已经转换为字节了不需要进行校验了将校验过程延后),也就是.dex 文件成功加载到了内存中
二,loadDexFile 实现细节

如果没有传入优化后的 odex 文件的路径,直接创建一个 DexFile(遍历到的 dex 文件,类加载器,dex 转换后的 Element 数组【开始遍历的时候会创建一个空的 Elements 数组,不断遍历进行添加直至所有 dex 文件全部加载完】)返回;【Element 中存放的为 DexFile 对象创建的时候会传入进去】
传入 odex 文件存放路径会使用 DexFile.loadDex 进行创建 DexFile 结构。
最后会进入到 native 层去加载
版权声明: 本文为 InfoQ 作者【北洋】的原创文章。
原文链接:【http://xie.infoq.cn/article/c5002381be1cfc5033b32f42b】。文章转载请联系作者。
评论