DexClassLoader
DexClassLoader继承于BaseDexClassLoader,可以加载自定义目录下的Dex文件,内部只有一个方法
public DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath,ClassLoader parent) {
super(dexPath, new File(optimizedDirectory), libraryPath, parent);
}
PathClassLoader
PathClassLoader同样继承于BaseDexClassLoader,可以加载已安装目录下的Dex文件,内部只有两个方法
public PathClassLoader(String dexPath, ClassLoader parent) {
super(dexPath, null, null, parent);
}
public PathClassLoader(String dexPath, String libraryPath, ClassLoader parent) {
super(dexPath, null, libraryPath, parent);
}
BaseDexClassLoader
BaseDexClassLoader继承于ClassLoader,在构造函数中生成DexPathList
this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
BaseDexClassLoader重写了findclass方法,ClassLoader在loadClass时,会调用findClass方法,findclass方法又调用pathlist里的方法
Class c = pathList.findClass(name, suppressedExceptions);
DexPathList
DexPathList是真正管理Dex的类,内部包含一个Dex数组和native数组
private final Element[] dexElements;
private final File[] nativeLibraryDirectories;
在构造函数中初始化dexElements
this.dexElements = makeDexElements(splitDexPath(dexPath),optimizedDirectory,suppressedExceptions);
在makeDexElements中遍历目录,加载dex,生成DexElement
dex = loadDexFile(file, optimizedDirectory);
elements.add(new Element(file, false, zip, dex));
在loadDexFile中加载Dex
return DexFile.loadDex(file.getPath(), optimizedPath, 0);
进行findclass操作时遍历数组,对逐个dex进行查找
for(Element element :dexElements){
DexFile dex = element.dexFile;
if (dex != null) {
Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
if (clazz != null) {
return clazz;
}
}
}