类加载-双亲委派

java和android都遵循双亲委派


ClassLoader的核心功能机制:

  1. IO读取Class文件,解析,分配栈、堆,加载到永久代(Perm区)
  2. 双亲委托寻找 & 加载

java

  1. BootstrapclassLoader:主要负责加载核心的类库(java.lang.*等),构造ExtClassLoader和APPClassLoader。
  2. ExtClassLoader:主要负责加载jre/lib/ext目录下的一些扩展的jar。
  3. AppClassLoader:主要负责加载应用程序的主函数类4.通过继承 java.lang.ClassLoader 实现自定义的类加载器

双亲委派是一个孩子向父亲方向,然后父亲向孩子方向的双亲委派过程
总结:自下(从App开始)而上进行检查,自上而下进行加载


Android

每个 Class 对象的内部都有一个 classLoader 字段来标识自己是由哪个ClassLoader 加载的。
class Class {

private transient ClassLoader classLoader;

}

ClassLoader是一个抽象类,而它的具体实现类主要有:

  1. BootClassLoader:用于加载Android Framework层class文件。
  2. PathClassLoader:用于Android应用程序类加载器。可以加载指定的dex,以及jar、zip、apk中的classes.dex
  3. DexClassLoader:用于加载指定的dex,以及jar、zip、apk中的classes.dex

PathClassLoader 中存在一个Element数组

APK中有X个dex,则Element数组就有X个元素

热修复:一种热修复实现可以将出现Bug的class单独的制作一份fix.dex文件(补丁包),然后在程序启动时,从服务器下载fix.dex保存到某个路径,再通过fix.dex的文件路径,用其创建 Element 对象,然后将这个 Element 对象插入到我们程序的类加载器 PathClassLoader 的 pathList 中的 dexElements 数组头部。这样在加载出现Bug的class时会优先加载fix.dex中的修复类,从而解决Bug。

机制的作用:

主要是为了安全,这种机制下,防止系统类被篡改,因为系统类已经被Bootstrap classLoader加载过了

而且平时大部分时间都是应用类的加载,如果加载过了,那么在第一步就会停止,效率很高

和网上的说法类似:

1、避免重复加载,当父加载器已经加载了该类的时候,就没有必要子ClassLoader再加载一次。

2、安全性考虑,防止核心API库被随意篡改。

抖音解释

Android 中 ClassLoader 情况。一般情况下 Android 中有两个 ClassLoader,分别是 BootClassLoader 和 PathClassLoader,BootClassLoaderart 负责加载 android sdk 的类,像我们的 Activity、TextView 等都由 BootClassLoader 加载。PathClassLoader 则负责加载 App 中的类,比如我们的自定义的 Activity、support 包中的 FragmentActivity 这些会被打进 app 中的类则由 PathClassLoader 进行加载。BootClassLoader 是 PathClassLoader 的 parent。