Android-ClassLoader学习记录

目录

  1. 类加载简述
  2. Android类加载的主要相关类
  3. 创建过程
  4. 参考

类加载简述

虚拟机把描述数据的字节码文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成被虚拟机直接使用的class类型。

Android类加载的主要相关类

以Android 10源码为主

  • ClassLoader抽象类,源码位于java.lang包下,是所有加载类的基类。其构造函数需要传parent classloader,如果传null,则默认为PathClassLoader。定义若干重要函数:

    • loadClass 如何加载指定类: 定义了双亲委派模型,parent加载不到时才会使用findClass, 通常不要override去违背该模型
    • findClass 如何查找指定类: 子类实现通常需override该方法
    • defineClass 根据字节数组加载类,Android中不允许使用
  • BootClassLoader继承ClassLoader,源码位于java.lang包下,所有加载类的parent,负责加载系统类和Framework类等: 这保证了类似String类必须使用系统预先定义好的,不允许自定义,提高安全性。

  • BaseDexClassLoader是Android使用类加载器的基类,保证Android只允许加载dex结构字节码。

    • 构造函数传入变量dexPath,表示加载dex所在路径,可以多路径通过File.pathSeparator区分;如果是jar/apk文件,其中含有*.dex也可以。
    • 重载findClass函数,真正实现查找的类是DexPathList
  • PathClassLoader继承BaseDexClassLoader,Android系统使用该类加载系统类和应用类,所以系统设置其dexPath为/data/app/<packagename>/*.apk

  • DexClassLoader继承BaseDexClassLoader,提供给第三方加载执行应用未安装代码的能力。

  • DexPathList真正实现查找类:根据dexPath把每个dex文件封装成Element对象,这些Element对象排列成有序数组dexElement,依次遍历去查找指定类,最终会调用至DexFiledefineClassNative方法,通过native实现的。

创建过程

  • ZygoteInit类执行main过程中会调用preloadClasses()方法,其作用是预加载/system/etc/preloaded-classes中声明的类,这包括类似java.lang包的基础类和Activity等框架类等,这时候会创建BootClassLoader去加载这些类。

  • ZygoteInitforkSystemServer进程后,在#handleSystemServerProcess方法中最终会创建PathClassLoader

参考

  1. 源码

  2. https://developer.android.com/reference/dalvik/system/