众所周知,Java程序运行过程是这样的。首先,Java源码编译器将java文件编译成二进制的字节码class文件。然后,Java虚拟机再运行class文件。class文件是怎么加载到JVM里面的呢?答案是通过 ClassLoader 的加载机制。安卓虚拟机也有类似这样的机制,为了能编写出更高效的代码,我们有必要了解下ClassLoader 的加载机制。本文先会分别详解安卓的 ClassLoader。
01
Java 的 ClassLoader
大多数安卓应用程序是由Java语言开发的。所以有必要先了解Java 的 ClassLoader。Java加载类的过程主要由系统自带的三个类加载器依次被执行来加载类的。有图有真相,下图能让人一目了然:
1)Bootstrap ClassLoader
:
最顶层的加载类。负责从引导类路径中加载核心类。主要加载 %JRE_HOME%\lib
下的 rt.jar、resources.jar、charsets.jar 和 class等
2)Extention ClassLoader
:
扩展的类加载器。负责加载目录 %JRE_HOME%\lib\ext
目录下的jar包和class文件
3)App ClassLoader
:
系统类加载器。负责加载应用程序级类路径以及环境变量(classpath)的所有类
这三个类加载器Boot Strap
、Extension
、Application
是位于类加载器子系统(Class Loader Subsystem)中。类加载器子系统主要是将class文件进行加载、链接、初始化。其是JVM架构的第一层。
02
Android 的 ClassLoader
了解了Java的ClassLoader, 接下来了解Android 的 ClassLoader 就易如反掌。Java有虚拟机,Android系统中也是有两种虚拟机的。Android系统在5.0以前的虚拟机是采用Dalvik虚拟机。从系统5.0以后,Android Runtime虚拟机取代Dalvik成为系统内默认虚拟机。安卓虚拟机运行加载的不是class文件,而是dex文件。dex文件是编译工具把所有的class文件进行合并,优化,然后生成的。
Android中类加载器有BootClassLoader
, URLClassLoader
, PathClassLoader
, DexClassLoader
, BaseDexClassLoader
等。
同样一张图让你明白类加载的过程:
1)ClassLoader
ClassLoader 是一个抽象类。它是所有类加载器的父类。我们一般是使用其具体的子类DexClassLoader、PathClassLoader。
2)BootClassLoader
在Android虚拟机中,BootClassLoader是ClassLoader内部类。同时,也是Android平台上所有ClassLoader的最终parent。 这个内部类是包内可见, 所以我们没法使用。
3)URLClassLoader
只能用于加载jar文件,但是由于 dalvik 不能直接识别jar,所以在 Android 中无法使用这个加载器。
4)BaseDexClassLoader
PathClassLoader和DexClassLoader都继承自BaseDexClassLoader。但是其中的主要逻辑都是在BaseDexClassLoader完成的。
BaseDexClassLoader
类的部分源码如下:
从源码中,我们得知BaseDexClassLoader
的构造方法包含四个参数,这四个参数代表的意思如下:
5)DexClassLoader
我们不妨先看看该类的构造方法。因为平时开发中,可能会使用到。
DexClassLoader可以加载jar/apk/dex,可以从SD卡中加载未安装的apk;
6)PathClassLoader
同样先看看其构造方法。
PathClassLoader只能加载系统中已经安装过的apk;
作者:猴哥,公众号:极客猴。爱好读书,喜欢钻研技术,梦想成为文艺青年的IT Boy。
- END -