ClassLoader 类型JAVA 中的 ClassLoader 可以加载 jar 文件和 Class文件(本质是加载 Class 文件),这一点在 Android 中并不适用,因为无论 DVM 还是 ART 它们加载的不再是 Class 文件,而是 dex 文件 。
Android 中的 ClassLoader 类型和 Java 中的 ClassLoader 类型类似,也分为两种类型,分别是 系统 ClassLoader 和 自定义 ClassLoader。其中 Android 系统 ClassLoader 包括三种分别是 BootClassLoader 、 PathClassLoader 和 DexClassLoader,而 Java 系统类加载器也包括3种,分别是 Bootstrap ClassLoader 、 Extensions ClassLoader 和 App ClassLoader。
BootClassLoaderAndroid 系统启动时会使用 BootClassLoader 来预加载常用类,与 Java 中的 BootClassLoader 不同,它并不是由 C/C++ 代码实现,而是由 Java 实现的,BootClassLoade 的代码如下所示
// libcore/ojluni/src/main/java/java/lang/ClassLoader.javaclass BootClassLoader extends ClassLoader {private static BootClassLoader instance;@FindBugsSuppressWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED")public static synchronized BootClassLoader getInstance() {if (instance == null) {instance = new BootClassLoader();}return instance;}public BootClassLoader() {super(null);}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {return Class.classForName(name, false, null);}...}BootClassLoader 是 ClassLoader 的内部类,并继承自 ClassLoader。BootClassLoader 是一个单例类,需要注意的是 BootClassLoader 的访问修饰符是默认的,只有在同一个包中才可以访问,因此我们在应用程序中是无法直接调用的。
PathClassLoaderAndroid 系统使用 PathClassLoader 来加载系统类和应用程序的类,如果是加载非系统应用程序类,则会加载 data/app/$packagename 下的 dex 文件以及包含 dex 的 apk 文件或 jar 文件,不管是加载哪种文件,最终都是要加载 dex 文件,在这里为了方便理解,我们将 dex 文件以及包含 dex 的 apk 文件或 jar 文件统称为 dex 相关文件 。 PathClassLoader 不建议开发直接使用 。
// libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.javapublic class PathClassLoader extends BaseDexClassLoader {public PathClassLoader(String dexPath, ClassLoader parent) {super(dexPath, null, null, parent);}public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {super(dexPath, null, librarySearchPath, parent);}}PathClassLoader 继承自 BaseDexClassLoader,很明显 PathClassLoader 的方法实现都在 BaseDexClassLoader 中 。
PathClassLoader 的构造方法有三个参数:
- dexPath:dex 文件以及包含 dex 的 apk 文件或 jar 文件的路径集合,多个路径用文件分隔符分隔,默认文件分隔符为‘:’ 。
- librarySearchPath:包含 C/C++ 库的路径集合,多个路径用文件分隔符分隔分割,可以为 null
- parent:ClassLoader 的 parent
public class DexClassLoader extends BaseDexClassLoader {public DexClassLoader(String dexPath, String optimizedDirectory,String librarySearchPath, ClassLoader parent) {super(dexPath, null, librarySearchPath, parent);}}DexClassLoader 构造方法的参数要比 PathClassLoader 多一个 optimizedDirectory 参数,参数 optimizedDirectory 代表什么呢?应用程序在第一次被加载的时候,为了提高以后的启动速度和执行效率,Android 系统会对 dex 相关文件做一定程度的优化,并生成一个 ODEX 文件,此后再运行这个应用程序的时候,只要加载优化过的 ODEX 文件就行了,省去了每次都要优化的时间,而参数 optimizedDirectory 就是代表存储 ODEX 文件的路径,这个路径必须是一个内部存储路径 。PathClassLoader 没有参数 optimizedDirectory,这是因为 PathClassLoader 已经默认了参数 optimizedDirectory 的路径为: /data/dalvik-cache。DexClassLoader 也继承自 BaseDexClassLoader,方法实现也都在 BaseDexClassLoader 中 。关于以上 ClassLoader 在 Android 系统中的创建过程,这里牵扯到 Zygote 进程,非本文的重点,故不在此进行讨论 。
ClassLoader 继承关系

文章插图
- ClassLoader 是一个抽象类,其中定义了 ClassLoader 的主要功能 。BootClassLoader 是它的内部类 。
- SecureClassLoader 类和 JDK8 中的 SecureClassLoader 类的代码是一样的,它继承了抽象类 ClassLoader。SecureClassLoader 并不是 ClassLoader 的实现类,而是拓展了 ClassLoader 类加入了权限方面的功能,加强了 ClassLoader 的安全性 。
推荐阅读
- 使用Apache协议的是自由软件吗?
- 昆仑雪菊胎菊冲泡方式,昆仑雪菊茶的冲泡步骤
- 景洪勐宋古茶山,勐宋古茶山滑竹梁子
- 苦丁的功效与作用,发酵小叶苦丁茶的功效与作用
- Python实现数据压缩如此简单
- 禁忌喝的八种茶,喝苦瓜茶的禁忌
- 不要忽视 .gitignore
- 喝清茶能减肥吗,喝青茶能减肥吗
- 经期喝生姜茶可以么,经期喝什么茶
- 很少使用但很方便的HTML标签
