子类:BaseDexClassloader 的子类

               1 PathClassLoader,==》用于android应用程序的类加载器,可以加载制定的dex,以及j a r,zip,apk中的classes。dex 

                 2 inMamemoryDexClassLoader =>android 8.0之后添加的,用来加载内存中的                                                         dex文件

                  3 DexClassLoader ==》加载指定的dex,以及jar,zip,apk中的classes.dex

 其中,我们自己写的ma inactivity等是被PathClassLoader加载的。

        但系统的Activity.class 是被 =》bootCalsss Loader加载的,这个加载的是Framework 层的class文件.例如下面的两个返回就是不一样的。


//Path Class Loader
val classLoader1 =getclassLoader

// Boot Class Loader
val classLoader2 = Activity.class.getclassLoader
DexClassLoader 和 PathClassLoader 区别。

直接看两个构造方法:都是可以加载额外的de x的,几乎没有区别,有些博客说的错的

/**

1.DexClassLoader需要传入opt优化后的optdex的文件存放路径,
2.但是PathClassLoader 传的null,PathClassLoader所以不优化?
不是的,也会加载优化,PathClassLoader会存到“/data/davlic-cache”里面去
3. optimizedDirectory -》必须是app的私有目录。不能用sd card,
*/

  public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) {
        super((String)null, (File)null, (String)null, (ClassLoader)null);
        throw new RuntimeException("Stub!");
    }


public class PathClassLoader extends BaseDexClassLoader {
    public PathClassLoader(String dexPath, ClassLoader parent) {
        super((String)null, (File)null, (String)null, (ClassLoader)null);
        throw new RuntimeException("Stub!");
    }

    public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
        super((String)null, (File)null, (String)null, (ClassLoader)null);
        throw new RuntimeException("Stub!");
    }
}

那么Class Loader又是怎么加载dex的呢?

        dex  加载都是先从parent父类开始找,不停往上找,找不到,再来找自己本身,这里说的是parent父亲,不是指的继承关系里的父类

1.双亲委托机制;某个类加载器加载类时,首先加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就返回成功,否则自己去加载。

接下来就是BaseDexLoader中的 find 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;
    }

///主要就是 Class c = pathList.findClass(name, suppressedExceptions);

pathList? 又是什么呢?还是源码里。

private final DexPathList pathList;并且在构造方法中。

public BaseDexClassLoader(String dexPath, File optimizedDirectory,
            String librarySearchPath, ClassLoader parent, boolean isTrusted) {
        super(parent);
        this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted);

        if (reporter != null) {
            reportClassLoaderChain();
        }
    }

继续挖。。。。

 public Class<?> findClass(String name, List<Throwable> suppressed) {
        for (Element element : dexElements) {
            Class<?> clazz = element.findClass(name, definingContext, suppressed);
            if (clazz != null) {
                return clazz;
            }
        }

        if (dexElementsSuppressedExceptions != null) {
            suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
        }
        return null;
    }

注意:Element中包含一个dexfile,

再后面就是记录dex地址,和dex的opt优化的地址。----》loadDexFile --->kotlin里面会提示不推荐= =

loadDexFile,遍历de x的所有所有class。

最后还是很多的native(c/c++)函数,来完成加载。

Elementz中的find Class(),就是借助DexFile,DexFile加载一个类,DexFile通过native defineClassNAtive()这样的方法

12-19 17:49