Android 类加载器简析

2018-02-10  本文已影响26人  一半晴天

初略翻了一下 Android 的源代码。发现 Android 主要有如下几个类加载器。

  1. Boot 加载器
  2. 系统加载器

系统加载器简析

系统加载器由是 PathClassLoader 类的实例。
PathClassLoader 继承自 BaseDexClassLoader,
DexClassLoader 也继承自 BaseDexClassLoader

BaseDexClassLoader

BaseDexClassLoader 才是 Android 应用类加载器的主要逻辑所在。
PathClassLoaderDexClassLoader 只是继承了 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();
 }

对于构造函数参数的解释。

  1. dexPath 由 ":" 分隔的 jar/apk 文件列表。
  2. librarySearchPath 由 ":" 分隔的包含了原生库的目录的列表。
  3. optimizedDirectory 此参数已被废弃。
  4. parent 父类加载器。

DexPathList

BaseDexClassLoaderfindClass 的逻辑主要委托给 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;
}
上一篇下一篇

猜你喜欢

热点阅读