Android动态加载技术基础之类加载(ClassLoader)

2018-07-26  本文已影响0人  抽象语法树

虚拟机类加载机制

类加载的过程

虚拟机类加载过程分为加载,验证,准备,解析,初始化,使用,卸载七个阶段。其中验证,准备,解析三个部分成为连接阶段。

加载

一般来说,在遇到了以下四种情况的时候,虚拟机会开始进行类的加载:

验证

这一阶段是为了确保class文件的字节流包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。主要包括以下几个过程:

准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。这个阶段中进行内存分配的变量只有被static修饰的变量,并将其设置为默认值,而真正的赋值则在初始化阶段。另外,被final static字段修饰的常量在编译器就已经被赋值。

解析

解析阶段主要是虚拟机将常量池内的符号引用替换为直接引用的过程。

初始化

初始化阶段是执行类构造器<cinit>()方法的过程。
<cinit>()与类的构造方法不同,<cinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并而成的。编译器收集的顺序是按语句在源文件中出现的顺序决定的,静态语句块中只能访问定义在它之前的静态变量,定义在它之后的静态变量,只可以赋值,不可以访问。
虚拟机会保证子类的<cinit>()方法执行之前,其父类的<cinit>()方法一定被执行(父类先与子类完成加载过程)

Java中的ClassLoader

类加载阶段中,实现“通过一个类的全限定名获取定义类的二进制字节流”的动作被放在了虚拟机外部去实现,以便应用程序决定如何去加载所需要的类,实现这个动作的代码模块被称为“类加载器”
从Java虚拟机的角度上讲,只存在两种不同的类加载器:

类的双亲委派模型

这些类加载器之间的关系如下:


类加载器

双亲委派模型中,除了顶层的BootstrapClassLoader,其他类加载器都要求有自己的父类加载器,这里的类加载器一般以组合的方式实现。

Android中的ClassLoader

Android的ClassLoader类型

Android中的ClassLoader根据用途可分为一下几种:

Android中ClassLoader的继承关系

ClassLoader

ClassLoader的执行过程

ClasLoader

protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
    Class<?> clazz = findLoadedClass(className);
    if (clazz == null) {
        ClassNotFoundException suppressed = null;
        try {
            clazz = parent.loadClass(className, false);
        } catch (ClassNotFoundException e) {
            suppressed = e;
        }
        if (clazz == null) {
            try {
                clazz = findClass(className);
            } catch (ClassNotFoundException e) {
                e.addSuppressed(suppressed);
                throw e;
            }
        }
    }
    return clazz;
}

BaseDexClassLoader

DexClassLoader和PathClassLoader

上一篇 下一篇

猜你喜欢

热点阅读