原创内容,转载请注明出处,多谢配合。

这部分是针对动态加载插件的编译,主要是由ClassLoader来触发的,下面简单总结下。

一、Android 的ClassLoder介绍
1.1 ClassLoder类

ClassLoader 抽象父类 。
BootClassLoader 加载Android 系统编译文件。
BaseDexClassLoader PathClassLoader和DexClassLoader的父类,主要功能执行者。
PathClassLoader 加载已被安装的应用路径中.dex 文件。
DexClassLoader 加载指定路径中的.dex 文件。

1.2 初始化

getClassloader实际上就是选择对应classLoader并保证初始化的过程,常用的是Context去获取的。

/frameworks/base/core/java/android/app/ContextImpl.java@Overridepublic ClassLoader getClassLoader() { return mClassLoader != null ? mClassLoader : (mPackageInfo != null ? mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader());}

不管是LoadedApk. getClassLoader 还是ClassLoader.getSystemClassLoader(),针对系统级别的类加载都是PathClassLoader。

1.3 DexClassLoader与PathClassLoader构造方法说明

DexClassLoader与PathClassLoader均继承BaseDexClassLoader,内部只包含构造方法,真正的功能实现都在BaseDexClassLoader。

两者构造方法解析:

public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) { / /热修复使用这个    super((String)null, (File)null, (String)null, (ClassLoader)null);    throw new RuntimeException("Stub!"); }参数:dexPath:dex 文件路径列表,多个路径使用”:”分隔optimizedDirectory:经过优化的 dex 文件(odex)文件输出目录librarySearchPath:动态库路径(将被添加到 app 动态库搜索路径列表中)parent:这是一个 ClassLoader,这个参数的主要作用是保留 java 中 ClassLoader 的委托机制。
public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {     super((String)null, (File)null, (String)null, (ClassLoader)null);    throw new RuntimeException("Stub!"); }参数:dexPath:文件或者目录的列表librarySearchPath:包含 lib 库的目录列表parent:父类加载器

二、ClassLoader相关流程

先上流程图


Android 9.0 ART编译分析(三)-虚拟机触发dex2oat编译流程_第1张图片 动态加载插件直接触发dex2oat编译流程

注:这里loadClass线路点到为止,因为它并不是本篇文章的重点。

两条路线解析:
先走dex编译,再走loadClass类加载。

1)6-17是makeDexElements 保存dexElements 并触发dex编译过程

DexPathList有一个Element[] dexElements; 是用来保存dex/resource(class path) 的集合,由makeDexElements来收集。makeDexElements 方法会遍历所有dex path,并将它们一个个封装为Element,保存到Element[]中,长度不够通过copyOf翻倍扩容。另外会通过loadDexFile开始走编译路线。
编译的核心方法在oat_file_manager.cc中的OpenDexFilesFromOat,这里通过oat_file_assistant.cc 执行isUpToDate判断dex文件是否需要编译,如果需要走它的MakeUpToDate方法,执行编译。
MakeUpToDate中如果需要执行编译会走GenerateOatFileNoChecks,最终调用其Dex2Oat方法,调整好参数传给dex2oat这个执行文件去Exec。

2)1-5是loadClass类加载过程

在ClassLoader中执行classLoader:这里遵循双亲委派机制,先判断当前ClassLoader是否加载过,如果没有就让父类去加载,父类都不加载,再轮到子类去加载。
BaseDexClassLoader执行findClass,实际是通过DexPathList去执行findClass。
因为之前makeDexElements给Element[] dexElements赋值了,这里DexPathList执行的findClass实际上是遍历所有dexElements,每一个element都执行findClass
而最终是交给DexFile去做的类加载:其具体流程不赘述,跟java ClassLoader差不多:
顺序经历如下流程:

  • Loading:类的信息从文件中获取并加载到JVM内存中。
  • Verifying:检查读入的结构是否符合JVM规范。
  • Preparing:验证完正确,会分配一个结构来存储类信息。
  • Resolving: 把这个类的常量池中的所有符号引用转变为直接引用。
  • Initializing:执行静态初始化程序,把静态变量初始化成指定的值。

最终就是将dex字节码文件loader到内存,按虚拟机内存划分区域去存放对应的数据。

更多相关文章

  1. android 点击重新加载界面设计
  2. Android加载SD卡目录,文件夹遍历,图片设置,设置文件对应打开方式等
  3. 我的android 第9天 - 文件存储
  4. Android加载字体包及封装
  5. Android下拉刷新上拉加载控件,对所有View通用!
  6. Android之怎么操作文件(读写以及保存到sdcard)
  7. Android中strings.xml文件
  8. 三种方式实现自定义圆形页面加载中效果的进度条
  9. Android Studio导入.so库文件方法

随机推荐

  1. 面试篇--android下网络通讯机制(三种网络
  2. 获取手机系统
  3. Android(安卓)StateMachine和AsyncChanne
  4. Android中画图总结(1)
  5. android 自定义用相机拍照后的照片存储位
  6. android群发短信时判断短信是否发送成功
  7. Android触屏事件处理策略
  8. Android之百度地图开发,包含定位,覆盖物,经
  9. Android 图片加载总结帖
  10. Android: 用Instrumentation类发送鼠标或