本文所引用的代码为Android 6.0版本
简介
类图
先看看类图,画了几个类中主要的属性和方法。
大致介绍
- ClassLoader:抽象类,类加载器的顶级父类。
- BootClassLoader:ClassLoader子类,类修饰符省略,即package。该类只能被包内的程序访问。用于加载系统类,例如加载framework中的类。
- BaseDexClassLoader:ClassLoader子类。用于加载jar或apk文件。
- PathClassLoader:BaseDexClassLoader子类。用于加载安装的apk文件。
- DexClassLoader:BaseDexClassLoader子类。用于加载外部的jar或apk文件,也就是动态加载中所用的加载器。
不管是dalvik,还是art虚拟机,他们所使用的加载器基本都是这些类。
请尊重博主劳动成果,转载请标明原文链接且勿修改原文内容。
ClassLoader
位置:android-6.0.0_r1/libcore/libart/src/main/java/java/lang/ClassLoader.java
getSystemClassLoader()
采用静态内部来实现的单例模式。私有的静态内部类SystemClassLoader被加载进来时,会调用createSystemClassLoader()创建系统ClassLoader对象,并将其赋值给静态属性loader,以完成初始化操作。
static private class SystemClassLoader {
public static ClassLoader loader = ClassLoader.createSystemClassLoader();
}
public static ClassLoader getSystemClassLoader() {
return SystemClassLoader.loader;
}
当外部使用ClassLoader.getSystemClassLoader()
获取到的便是loader所引用的对象,即同一个进程内无论谁调用了这个方法,获取到的都是同一个对象。
在看看创建ClassLoader的createSystemClassLoader()方法。
private static ClassLoader createSystemClassLoader() {
String classPath = System.getProperty("java.class.path", ".");
...
// TODO Make this a java.net.URLClassLoader once we have those?
return new PathClassLoader(classPath, BootClassLoader.getInstance());
}
ClassLoader.getSystemClassLoader()获取到的为PathClassLoader对象。该对象的父加载器为BootClassLoader。classPath即为系统framework的类路径。
loadClass()
ClassLoader中非常重要的一个方法,也是经常被使用到的方法。
public Class<?> loadClass(String className) throws ClassNotFoundException {
return loadClass(className, false);
}
真正执行类加载的方法
protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
Class<?> clazz = findLoadedClass(className);
if (clazz == null) {
ClassNotFoundException suppressed = null;
try {
clazz = parent.loadClass(className, false);
} catch (ClassNotFoundException e) {
suppressed = e;
}
if (clazz == null) {
try {
clazz = findClass(clas