首先我们来看看下面代码

Dalvik虚拟机中ClassLoader的创建过程

我们知道,在Java中,类的加载是使用的委托机制,上面的代码就是打印ClassLoader的委托关系。它的运行结果如下:

Dalvik虚拟机中ClassLoader的创建过程

可以看到,我们应用的加载器是PathClassLoader,它的父加载器是BootClassLoader。下面我们通过代码来进行分析。

一、bootstrap class loader的初始化过程

system/framework/路径对应的就是BOOTCLASSPATH,对应系统相关jar包,在启动虚拟机之后,就需要对其进行加载,其实可以将其理解为顶层ClassLoader加载的相关jar包。

Dalvik虚拟机中ClassLoader的创建过程

1、读取BOOTCLASSPAT

Dalvik虚拟机中ClassLoader的创建过程

2、初始化bootstrap class loader

Dalvik虚拟机中ClassLoader的创建过程

上面的过程就是加载BOOTCLASSPATH下所有的jar和dex文件,并且每个jar或者dex文件都被一个ClassPathEntry引用,最终形成一个ClassPathEntry数组。
ClassPathEntry数组被gDvm.bootClassPath所引用,gDvm是一个全局变量。如下图所示:

Dalvik虚拟机中ClassLoader的创建过程

所以,如果我们需要加载这些jar文件中的某个类,我们就需要对整个数组进行遍历来获取对应的类的信息。其实BootClassLoader对类的查找过程就是遍历的整个数组来查找的,后面会具体介绍。所以,我们可以将它们对应到BootClassLoader中。

二、应用ClassLoader的创建过程

我们从Application的创建过程说起,直接看看ActivityThread.java

Dalvik虚拟机中ClassLoader的创建过程Dalvik虚拟机中ClassLoader的创建过程Dalvik虚拟机中ClassLoader的创建过程

可以看到,我们应用的ClassLoader的父ClassLoader就是BootClassLoader,这个也验证了前文开始的测试结果。

Dalvik虚拟机中ClassLoader的创建过程

三、BootClassLoader的findClass的调用过程

下面说说BootClassLoader的findClass的调用过程,它跟PathClassLoader或者DexClassLoader的findClass的调用过程不同。

Dalvik虚拟机中ClassLoader的创建过程Dalvik虚拟机中ClassLoader的创建过程Dalvik虚拟机中ClassLoader的创建过程

整个过程就是遍历gDvm.bootClassPath对应的ClassPathEntry数组进行查找。gDvm.bootClassPath的ClassPathEntry数组就是bootstrap class loader的初始化过程加载的系统jar文件。

四、PathClassLoader或者DexClasLoader的findClass的调用过程

整个过程就是前面一篇文章Dalvik虚拟机中Java类的加载过程讲过了,这里直接放一张图。

Dalvik虚拟机中ClassLoader的创建过程


双亲委派机制就是首先在父ClassLoader中进行类查找,一步步深入,如果没有找到就在自己的ClassLoader的查找,如下图所示。
Dalvik虚拟机中ClassLoader的创建过程

总结

上面对Android中Dalvik虚拟机中ClassLoader创建过程进行了讲解,主要分为两个部分,一个是bootstrap class loader,它在Java中对应的是BootClassLoader,一个是PathClassLoader或者DexClassLoader,它们的findClass是不同的,原因很简单,因为它们查找的范围是不一样的,一个是从系统的jar或者dex中进行查找,一个是从自己的加载的dex中进行查找,而整个查找过程使用的就是双亲委托机制。


Dalvik虚拟机中ClassLoader的创建过程

欢迎关注我的公众号:DroidMind

精品内容,独家发布

相关文章: