初略翻了一下 Android 的源代码。发现 Android 主要有如下几个类加载器。
- Boot 加载器
- 系统加载器
系统加载器简析
系统加载器由是 PathClassLoader
类的实例。
PathClassLoader
继承自 BaseDexClassLoader
,
DexClassLoader
也继承自 BaseDexClassLoader
BaseDexClassLoader
BaseDexClassLoader
才是 Android 应用类加载器的主要逻辑所在。
PathClassLoader
和 DexClassLoader
只是继承了 BaseDexClassLoader
然后提供了几个默认参数。
下面看一下 BaseDexClassLoader
的构造函数。
public BaseDexClassLoader(String dexPath, File optimizedDirectory,
String librarySearchPath, ClassLoader parent) {
super(parent);
this.pathList = new DexPathList(this, dexPath, librarySearchPath, null);
if (reporter != null) {
reportClassLoaderChain();
}
对于构造函数参数的解释。
-
dexPath
由 ":" 分隔的 jar/apk 文件列表。 -
librarySearchPath
由 ":" 分隔的包含了原生库的目录的列表。 -
optimizedDirectory
此参数已被废弃。 -
parent
父类加载器。
DexPathList
BaseDexClassLoader
中 findClass
的逻辑主要委托给 DexPathList
类的对象 pathList
来处理。
pathList
的构造过程: this.pathList = new DexPathList(this, dexPath, librarySearchPath, null);
DexPathList
的构造函数的主要逻辑如下:
// save dexPath for BaseDexClassLoader
this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,
suppressedExceptions, definingContext);
this.nativeLibraryDirectories = splitPaths(librarySearchPath, false);
this.systemNativeLibraryDirectories =
splitPaths(System.getProperty("java.library.path"), true);
List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories);
allNativeLibraryDirectories.addAll(systemNativeLibraryDirectories);
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories);
if (suppressedExceptions.size() > 0) {
this.dexElementsSuppressedExceptions =
suppressedExceptions.toArray(new IOException[suppressedExceptions.size()]);
} else {
dexElementsSuppressedExceptions = null;
}
DexFile
DexFile 的主要构造逻辑如下:
DexFile(String fileName, ClassLoader loader, DexPathList.Element[] elements) throws IOException {
mCookie = openDexFile(fileName, null, 0, loader, elements);
mInternalCookie = mCookie;
mFileName = fileName;
}
由于 DexPathList.Element
中的 findClass
如下:
public Class<?> findClass(String name, ClassLoader definingContext,
List<Throwable> suppressed) {
return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed)
: null;
}
即 DexFile.loadClassBinaryName
public Class loadClassBinaryName(String name, ClassLoader loader, List<Throwable> suppressed) {
return defineClass(name, loader, mCookie, this, suppressed);
}
基本 defineClass
的主要逻辑如下:
private static Class defineClass(String name, ClassLoader loader, Object cookie,
DexFile dexFile, List<Throwable> suppressed) {
Class result = defineClassNative(name, loader, cookie, dexFile);
return result;
}
网友评论