记录学习java 加载器学习所获心得,逐步记录了解java加载器的过程。为了知悉android 插件化的实现原理,从而需要从头了解android加载apk,以及基础的java类加载的加载过程情况,为方便记录和记忆,故此将学习了解的过程记录成文字,以下文字记录部分可能来自与多个来源,主体以Java源码和IBM开发者博客有关java加载技术的博客为主。

Java 类的加载过程

惯性思维,想要了解apk的加载过程,我希望先简单知道以下Java中对类加载过程的处理(Java一直都是android的官方开发语言,虽然现在kotlin也是,但原理不变)。首先需要了解Java 类在jvm中的加载过程,基本的流程如下:

  • 装载

    装载是通过已经编译生成的class文件的位置查找文件获取其字节流导入class文件,并将其转换成一个Class类的一个实例,将类的实例存放在jvm的堆区,获取装载类的信息到方法区(属于jvm的内存区域的一种,主要用于存放类的字段、方法,常量池等信息),这里就是负责处理完成类的加载的过程,主要是由ClassLoader及其子类完成。

  • 链接

    其主要功能就是对类信息格式进行校验,分配方法区域的类变量的初始值(并非设置的初始化数值,而是初始“0”值)并将类的引用指向对应类的实例。其内部分为三个过程:校验 —>准备—>解析。执行顺序为既定的。

  • 初始化

    初始化类的静态变量和静态代码块(相对于链接中的准备阶段,将已经“初始化”的静态数据进行真正的初始化).类的初始化情况:

    1)遇到类的创建指令New指令

    2)java主运行程序的入口类的实例

    3)通过反射创建类(newInstance、forClass等)

    4)子类初始化触发父类的初始化操作

    5)java 1.7动态类型初始化

  • 使用和卸载

    对创建java对象的操作以及java回收机制对jvm的自动回收卸载。

Java 类加载器

如上,对于java类的加载使用,属于应用层程序员可控过程就只有类的加载过程,通过指定类的加载器来加载我们的类信息,首先通过java的源码文档来简单了解一下类加载的介绍。类加载器位置:

java.lang.ClassLoader.java

文档介绍为:类加载器主要负责加载类的对象,通过给定一个类的“二进制名称”,那么类加载器会尝试定位或身成类定义的数据信息。一般策略是将二进制名称转化为一个文件的名称并加载该类文件的二进制数据。数组类型的类的对象并不是由类加载器创建,而是java 运行时根据需要自动创建.数组类型的加载器由Class.getClassLoader()返回.该加载器与其元素类型的类加载器是相同的;如果该元素类型是基本类型,则该数组类没有类加载器。

程序可以通过继承ClassLoader的子类来扩展动态加载方式.类加载器支持双亲委托模型(通过委托父类查找资源的方式进行操作)查找类或类的资源.虚拟机的内置类加载器(称为 “bootstrap class loader”)本身没有父类加载器,但是可以将它用作 ClassLoader 实例的父类加载器……

如上,为部分对于ClassLoader的介绍文字.对于通用类加载器通常将其分为四个类型,如下介绍:

  • 引导型类加载器(bootstrap)

    该类加载器并没有父类类加载器,具体实现是通过原生代码实现(平台相关的),用于加载Java的核心代码,无法直接通过代码使用.

  • 扩展型类加载器

    它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。android中相当于java.lang.BootClassLoader

  • 系统类加载器(system class loader)

    它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()获取。android 中相当与dalvik.system.PathClassLoader.

  • 线程上下文类加载器

    用于设置和获取线程上下文的类加载器,若是未曾设置该加载器,线程上下文类加载器将继承自父线的上下文类加载器,而Java应用初始线程上下文类加载器为系统加载器,android中也就是继承自BaseDexClassLoader的子类加器PathClassLoader或者DexClassLoader加载器.

    基于Android 平台对于以上的加载器做一个简单的代码测试如下:


var loader=classLoader
while (loader != null) {
println("加载器类型:${loader.toString()}")
loader = loader.parent
} //输出结果如下 10-30 17:55:05.964 23338-23338/com.enjoytoday I/System.out: 加载器类型:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.enjoytoday-2/base.apk", zip file "/data/app/com.enjoytoday-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.enjoytoday-2/lib/arm64, /system/fake-libs64, /data/app/com.enjoytoday-2/base.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_dependencies_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_0_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_1_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_2_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_3_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_4_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_5_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_6_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_7_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_8_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_9_apk.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64, /system/vendor/lib64, /product/lib64]]]
10-30 17:55:05.964 23338-23338/com.enjoytoday I/System.out: 加载器类型:java.lang.BootClassLoader@d725e7d

Android 中的类加载器

Android 中的虚拟机是由dalvik来实现,dalvik并非典型的Java虚拟机。因此,其类的加载器和标准有所不同,对于dalvik而言,其并不可以直接识别加载class文件,而是对class打包成的dex文件进行加载。因此,Android源码对ClassLoader进行处理,并派生一个子类BaseDexClassLoader,其本质类似于jvm中的ClassLoader,确切的说可以说是一个Dex加载器。

基于Android 平台的类加载器结构如下:

  • BootClassLoader

    是属于ClassLoader的一个内部类,不可直接使用,每个ClassLoader中都存在一个parent(ClassLoader类型),父类加载器,而BootClassLoader属于最顶层的parent.

  • URLClassLoader

    这个是一个输入jar的加载器,在java中支持在线或本地指定jar文件来加载jar包,但由于android中dalvik并不可以识别class或者jar,只能加载dex,所以并不可以直接使用URLClassLoader来加载jar文件

  • BaseDexClassLoader

这个属于加载dex文件的加载器的实现,具体的加载逻辑在其中实现

  • PathClassLoader

    继承自BaseDexClassLoader,为默认apk安装使用的类加载器,会自动寻址apk安装后默认解压后的dex路径,目前dalvik并不支持使用PathClassLoader来加载未安装的apk,但也有文章说art可以实现,暂未验证,不能确认。

  • DexClassLoader

    继承自BaseDexClassLoader,可以直接加载dex,压缩文件(apk文件),jar文件,是实现android插件化一个重要的元素,可以帮我们完成对为安装的插件apk的加载过程.

android基本加载知识记录,已留备存。

Enjoytoday,EnjoyCoding

Android插件基础之类加载器学习的更多相关文章

  1. 黑马程序员:Java基础总结----类加载器

    黑马程序员:Java基础总结 类加载器   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个 ...

  2. Java基础之类加载器

    Java类加载器是用户程序和JVM虚拟机之间的桥梁,在Java程序中起了至关重要的作用,理解它有利于我们写出更优雅的程序.本文首先介绍了Java虚拟机加载程序的过程,简述了Java类加载器的加载方式( ...

  3. java类加载器学习2——自定义类加载器和父类委托机制带来的问题

    一.自定义类加载器的一般步骤 Java的类加载器自从JDK1.2开始便引入了一条机制叫做父类委托机制.一个类需要被加载的时候,JVM先会调用他的父类加载器进行加载,父类调用父类的父类,一直到顶级类加载 ...

  4. tomcat 7 中的类加载器学习

    tomcat 7自带很多junit测试用例,可以帮助我们窥探源码的秘密.以下使用来测试类加载器的一个测试用例.类加载器也是对象,他们用来将类从类从.class文件加载到虚拟机,这些已经讲了很多,深入j ...

  5. java基础之—类加载器

    要了解类加载器先要了解类的加载 一.类的加载(类的加载概述) 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 1.加载 就是指将clas ...

  6. Java类加载器学习笔记

    今后一段时间会全面读一下<深入理解Java虚拟机> 在这里先记一下在网上看到的几篇介绍 类加载器 的文章,等读到虚拟机类加载机制再详细介绍. 超详细Java中的ClassLoader详解 ...

  7. Java基础加强-类加载器

    /*类加载器*/ 把.class文件从硬盘上加载出来,将类的字节码(二进制)加载到内存中 /*类加载器及其委托机制*/ Java虚拟机中可以安装多个类加载器(可以自己编写),系统默认三个主要类加载器, ...

  8. JAVA基础_类加载器

    什么是类加载器 类加载器是Java语言在1.0版本就引入的.最初是为了满足JavaApplet需要.现在类加载器在Web容器和OSGI中得到了广泛的应用,一般来说,Java应用的开发人员不需要直接同类 ...

  9. java 基础之--类加载器的过程

    先来段代码,大家瞧瞧运行pritln的结果是什么?(认真想一想哦

随机推荐

  1. 用Selenium自动化测试时,让ChromeDriver中不显示“正受到自动测试软件控制”

    背景: 在用Selenium做自动化测试的时候,默认ChromeDriver是会提示“Chrom正受到自动测试软件控制”的.如下图这样.但我们有些场景下,不希望这个提示出现.本文探索了几种语言去掉这个 ...

  2. BZOJ11208 宠物收养所

    最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希 ...

  3. CoderForces-375D

    You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. We will ass ...

  4. webpack(四) --css样式及图片打包

    一.CSS样式打包 1. loader简介 由于Webpack打包入口目前只配置了一个index.js文件,那么其他需要被打包的文件都必须通过模块化方式引入该文件才行,而默认情况下,引入的文件必须是j ...

  5. zabbix监控系统系列

    来自网站:http://www.361way.com/zabbix-summarize/3335.html 一.zabbix的特点 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能 ...

  6. 【Python必学】Python爬虫反爬策略你肯定不会吧?

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 正文 Python爬虫反爬策略三部曲,拥有这三步曲就可以在爬虫界立足了: ...

  7. Python numpy的基本操作你一般人都不会

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.  PS:如有需要最新Python学习资料的小伙伴可以加点击下方链接自行获取 ...

  8. python3导入子模块

    基础知识 参考资料1上有一句话Regular packages are traditional packages as they existed in Python 3.2 and earlier. ...

  9. iSensor App Kit 测试之 MT9V111 MT9M111 MT9D111

    iSensor App Kit 可以调试测试一切常规的sensor,对于ccusb20底板,可以直接兼容官哥所有的dvp接口的摄像头,分辨率从30w到1400w均没问题. 今天又测试了三款sensor ...

  10. JS操作document对象

    找到对象: document.getElementById():返回对拥有指定 id 的第一个对象的引用. document.getElementsByName():返回带有指定名称的对象集合. do ...