赞
踩
1.启动类加载器(Bootstrap ClassLoader):这个类加载器负责放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库,用户无法直接使用。
2.扩展类加载器(Extension ClassLoader):这个类加载器由sun.misc.Launcher$AppClassLoader实现。它负责<JAVA_HOME>\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库。用户可以直接使用。
3.应用程序类加载器(Application ClassLoader):这个类由sun.misc.Launcher$AppClassLoader实现。是ClassLoader中getSystemClassLoader()方法的返回值。它负责用户路径(ClassPath)所指定的类库。用户可以直接使用。如果用户没有自己定义类加载器,默认使用这个。
4.自定义加载器:用户自己定义的类加载器。
某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,每一层的加载器都采用这种方式,直到委托给顶层的启动类加载器为止,如果超类无法加载该类,则会将类的加载内容退回给它的下一层。
- 双亲委托模式:可以避免重复加载,能有效的确保一个类的全局唯一性。
- 如果不使用这种委托模式,那我们就可以随时使用自定义的类来动态替代一些核心的类,存在非常大的安全隐患,比如定义 java.lang.String 替代系统的String等操作。
Android中包含以下几种ClassLoader
BaseDexClassLoader为核心类,androidStudio中是看不到BaseDexClassLoader源码的,提供下源码查看地址:BaseDexClassLoader.java
DexClassLoader是BaseDexClassLoader子类,下面分析参数。
- /**
- * 构造方法
- */
- public class BaseDexClassLoader extends ClassLoader {
- public BaseDexClassLoader(String dexPath, File optimizedDirectory,
- String librarySearchPath, ClassLoader parent) {
- }
- }
-
- /**
- * 构造方法
- */
- public class DexClassLoader extends BaseDexClassLoader {
- public DexClassLoader(String dexPath, String optimizedDirectory,
- String librarySearchPath, ClassLoader parent) {
- super(dexPath, null, librarySearchPath, parent);
- }
- }
dexPath:apk/dex/jar文件路径
optimizedDirectory:是odex将dexPath路径中dex优化后的输出路径,这个路径必须是手机内部路劲。此参数已弃用,自API级别26起不再生效。
librarySearchPath:需要加载的C/C++库路径
parent:父加载器(这个比较重要与Android加载class的机制有关)
BaseDexClassLoader构造方法中传入的参数最终会传给DexPathList,BaseDexClassLoader.findClass最终调用DexPathList.findClass。
- /**
- * 构造方法
- */
- public BaseDexClassLoader(String dexPath, File optimizedDirectory,
- String librarySearchPath, ClassLoader parent, boolean isTrusted) {
- super(parent);
- //DexPathList
- this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted);
-
- if (reporter != null) {
- reportClassLoaderChain();
- }
- }
-
- /**
- * BaseDexClassLoader.findClass
- */
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
- //DexPathList.findClass
- 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;
- }
- /**
- * List of dex/resource (class path) elements.
- * Should be called pathElements, but the Facebook app uses reflection
- * to modify 'dexElements' (http://b/7726934).
- */
- private Element[] dexElements;
-
- /**
- * DexPathList.findClass
- */
- public Class<?> findClass(String name, List<Throwable> suppressed) {
- //dexElements数组
- 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;
- }
-
- /**
- * dexElements初始化赋值
- */
- private static Element[] makeDexElements(List<File> files, File optimizedDirectory,
- List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) {
- Element[] elements = new Element[files.size()];
- int elementsPos = 0;
- /*
- * Open all files and load the (direct or contained) dex files up front.
- */
- for (File file : files) {
- if (file.isDirectory()) {
- // We support directories for looking up resources. Looking up resources in
- // directories is useful for running libcore tests.
- elements[elementsPos++] = new Element(file);
- } else if (file.isFile()) {
- String name = file.getName();
- DexFile dex = null;
- if (name.endsWith(DEX_SUFFIX)) {
- // Raw dex file (not inside a zip/jar).
- try {
- dex = loadDexFile(file, optimizedDirectory, loader, elements);
- if (dex != null) {
- elements[elementsPos++] = new Element(dex, null);
- }
- } catch (IOException suppressed) {
- System.logE("Unable to load dex file: " + file, suppressed);
- suppressedExceptions.add(suppressed);
- }
- } else {
- try {
- dex = loadDexFile(file, optimizedDirectory, loader, elements);
- } catch (IOException suppressed) {
- /*
- * IOException might get thrown "legitimately" by the DexFile constructor if
- * the zip file turns out to be resource-only (that is, no classes.dex file
- * in it).
- * Let dex == null and hang on to the exception to add to the tea-leaves for
- * when findClass returns null.
- */
- suppressedExceptions.add(suppressed);
- }
- if (dex == null) {
- elements[elementsPos++] = new Element(file);
- } else {
- elements[elementsPos++] = new Element(dex, file);
- }
- }
- if (dex != null && isTrusted) {
- dex.setTrusted();
- }
- } else {
- System.logW("ClassLoader referenced unknown path: " + file);
- }
- }
- if (elementsPos != elements.length) {
- elements = Arrays.copyOf(elements, elementsPos);
- }
- return elements;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。