Android 进阶解密阅读笔记14
本节来说说 ClassLoader。首先明确一点它的作用就是用来查找和加载 Class 文件到虚拟机中。在 Java 中加载的是 jar 文件及 Class 文件,而在 Android 里显然虚拟机加载的是 dex 文件,所以 Android 里的 ClassLoader 加载的就是 dex 文件。
ClassLoader 类
这个类是个抽象类,其功能我觉得是规范了一套查找和加载的机制,Java 和 Android 的类加载器都继承自它(当然 Java 的 Bootstrap ClassLoader 没有继承它)。
Load 的本质操作
这点是抛开具体实现来说,不管 Android 还是 Java 的 ClassLoader 有几种或者各自负责什么功能,其本质思路都是「从某个路径下读取 Class 文件/ dex 文件,以字节数组的形式加载到内存,再根据语法转为 Class 类」
具体实现
Java 的类加载器在查找的时候采用的是双亲委派机制(parents delegation) 也就是说查找工作从最底层的类加载器(可能是自定义或者 AppClassLoader )开始,先交给双亲,如果双亲还有双亲,就继续委派,直到顶层类加载器(Bootstrap ClassLoader),所以查找总是从顶层开始,再一路往下,如果找到了就返回,要是直到最底层也没找到就抛异常。
同样 Android 也沿用了这套机制,只是类加载器不同,最底层类加载器可能是自定义或者 PathClassLoader,最顶层是 BootClassLoader。
这种机制有什么好处或作用呢?
- 避免相同的类重复加载
- 确保安全,只有类名完全相同且被同一个类加载器加载才算同一个类,防止了系统类被调包。
另外再说一点,这个机制的名称叫双亲,很多人会想那应该有两个,我一开始也这么认为,要解释这个还得从英文名着手,因为这个是翻译过来的叫法。前面标注了英文叫法,你就会发现,其实就是指 parent 一个,包括看源码也可以知道,就是父亲委派这个意思,没有两个。
Java 中的主要类加载器
- AppClassLoader
- ExtClassLoader
- BootstrapClassLoader,该类不是 Java 实现的。
Android 中的主要类加载器
- PathClassLoader
它是在 Zygote 进程启动时,执行 ZygoteInit.main 方法创建 SystemServer 进程时创建的。 - DexClassLoader
- BaseDexClassLoader
- BootClassLoader
它是在 Zygote 进程启动时,执行 ZygoteInit.main 方法预加载类时创建的,要先于 PathClassLoader 创建,且是个单例类。