美文网首页
Android 类加载器简析

Android 类加载器简析

作者: 一半晴天 | 来源:发表于2018-02-10 21:20 被阅读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;
    }
    

    相关文章

      网友评论

          本文标题:Android 类加载器简析

          本文链接:https://www.haomeiwen.com/subject/jvyqtftx.html