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