子类: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方法了。
@Overrideprotected 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()这样的方法