DexClassLoader 是加载包含classes.dex文件的jar文件或者apk文件; 通过构造函数发现需要一个应用私有的,可写的目录去缓存优化的classes。可以用使用File dexoutputDir = context.getDir(“dex”,0);创建一个这样的目录,不要使用外部缓存,以保护你的应用被代码注入。
其源码如下:
public classDexClassLoaderextendsBaseDexClassLoader {
37 /** 38 * Creates a { @code DexClassLoader} that finds interpreted and native 39 * code. Interpreted classes are found in a set of DEX files contained 40 * in Jar or APK files. 41 * 42 * <p>The path lists are separated using the character specified by the 43 * { @code path.separator} system property, which defaults to { @code :}. 44 * 45 * @param dexPath the list of jar/apk files containing classes and 46 * resources, delimited by { @code File.pathSeparator}, which 47 * defaults to { @code ":"} on Android 48 * @param optimizedDirectory directory where optimized dex files 49 * should be written; must not be { @code null} 50 * @param libraryPath the list of directories containing native 51 * libraries, delimited by { @code File.pathSeparator}; may be 52 * { @code null} 53 * @param parent the parent class loader 54 */ 55 public DexClassLoader(String dexPath, String optimizedDirectory, 56 String libraryPath, ClassLoader parent) { 57 super(dexPath, new File(optimizedDirectory), libraryPath, parent); 58 } 59} 60
再解释下几个构造函数参数的意义:
dexpath为jar或apk文件目录。
optimizedDirectory为优化dex缓存目录。
libraryPath包含native lib的目录路径。
parent父类加载器。
然后执行的是父类的构造函数:
super(dexPath, new File(optimizedDirectory), libraryPath, parent);
BaseDexClassLoader 的构造函数如下:
public BaseDexClassLoader(String dexPath, File optimizedDirectory,String libraryPath, ClassLoader parent) {
super(parent);
this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
}
第一句调用的还是父类的构造函数,也就是ClassLoader的构造函数:
protected ClassLoader(ClassLoader parentLoader) {
this(parentLoader, false);
}
/*
* constructor for the BootClassLoader which needs parent to be null.
*/
ClassLoader(ClassLoader parentLoader, boolean nullAllowed) {
if (parentLoader == null && !nullAllowed) {
throw new NullPointerException(“parentLoader == null && !nullAllowed”);
}
parent = parentLoader;
}
该构造函数把传进来的父类加载器赋给了私有变量parent。
再来看第二句:
this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
pathList为该类的私有成员变量,类型为DexPathList,进入到DexPathList函数:
/** 78 * Constructs an instance. 79 * 80 * @param definingContext the context in which any as-yet unresolved 81 * classes should be defined 82 * @param dexPath list of dex/resource path elements, separated by 83 * { @code File.pathSeparator} 84 * @param libraryPath list of native library directory path elements, 85 * separated by { @code File.pathSeparator} 86 * @param optimizedDirectory directory where optimized { @code .dex} files 87 * should be found and written to, or { @code null} to use the default 88 * system directory for same 89 */ 90 public DexPathList(ClassLoader definingContext, String dexPath, 91 String libraryPath, File optimizedDirectory) { 92 93 if (definingContext == null) { 94 throw new NullPointerException("definingContext == null"); 95 } 96 97 if (dexPath == null) {