Android Class加载机制(未完)

来源:互联网 发布:数据挖掘 招聘 银行 编辑:程序博客网 时间:2024/05/22 12:20

这篇文章主要讲述Android内的Class加载机制,主要分为JAVA和Native的两部分。

一、ClassLoader

JAVA层的Class加载本质就是ClassLoader的内容,我们首先来看下类的关系吧。

DexClassLoader和PathClassLoader继承BaseDexClassLoader。BaseDexClassLoader关键的方法findClass(String name),根据类名加载Class,我们以这里作为入口来看看是怎么实现的。
    @Override    protected Class<?> findClass(String name) throws ClassNotFoundException {        List<Throwable> suppressedExceptions = new ArrayList<Throwable>();        Class c = pathList.findClass(name, suppressedExceptions);        if (c == null) {            ClassNotFoundException cnfe = new ClassNotFoundException("Didn't find class \"" + name + "\" on path: " + pathList);            for (Throwable t : suppressedExceptions) {                cnfe.addSuppressed(t);            }            throw cnfe;        }        return c;    }

这个函数通过pathList来查找类,这个pathList类型是DexPathList。
    public Class findClass(String name, List<Throwable> suppressed) {        for (Element element : dexElements) {            DexFile dex = element.dexFile;            if (dex != null) {                Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);                if (clazz != null) {                    return clazz;                }            }        }        if (dexElementsSuppressedExceptions != null) {            suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));        }        return null;    }

findClass是通过DexPathList内的Element数组来顺序查找的。
DexPathList这个类是用来保存和ClassLoader相关的dex和resource加载路径资源的,它里面保存着一个Element数组
        private final File file;        private final boolean isDirectory;        private final File zip;        private final DexFile dexFile;

从上面可以看到,Element可以存储普通文件,zip和DexFile,findClass的时候就是顺序去数组里面查看每一个Element里面的DexFile是否可以加载Class。Element[]相关的信息是从DexPathList构造函数传入,然后通过makeDexElements来解析,makeDexElements的过程这里面不细讲,我们来看下DexPathList的构造函数
    /**     * Constructs an instance.     *     * @param definingContext the context in which any as-yet unresolved     * classes should be defined     * @param dexPath list of dex/resource path elements, separated by     * {@code File.pathSeparator}     * @param libraryPath list of native library directory path elements,     * separated by {@code File.pathSeparator}     * @param optimizedDirectory directory where optimized {@code .dex} files     * should be found and written to, or {@code null} to use the default     * system directory for same     */    public DexPathList(ClassLoader definingContext, String dexPath, String libraryPath, File optimizedDirectory)

可以看到一些lib和dex的信息就是从这里来的。好的,让我们来探讨下PathClassLoader和DexClassLoader的区别,
他们俩最大的区别在于构造函数的传参,体现在生成DexPathList的optimizedDirectory上面,DexClassLoader是可以传该变量的,而PathClassLoader没有,因此,DexPathList可以加载外部的dex文件,而PathClassLoader则不能。

0 0
原创粉丝点击