Android插件基础之类加载器学习

记录学习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=classLoaderwhile (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 平台的类加载器结构如下:

android dex加载结构

  • 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

转载于:https://www.cnblogs.com/amiko/p/7906204.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/287321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《看聊天记录都学不会C语言?太菜了吧》(13)(9*9 乘法表)寻找电脑中的盲盒彩蛋

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我,若你是真心学习可以送你书籍,指导你学习,给予你目标方向的学习路线,无套路,博客为证。 本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖…

Fragment使用--文章集锦

android使用Fragment实现底部菜单使用show()和hide()来切换以保持Fragment状态Android Fragment 真正的完全解析(上)Android Fragment实践(一)纠正对Fragment Transaction BackStack的误解多个Fragment 切换时不重新实例化Fragment详解之四——管理Fragm…

使用 Postman 实现 API 自动化测试

1背景介绍 相信大部分开发人员和测试人员对 postman 都十分熟悉,对于开发人员和测试人员而言,使用 postman 来编写和保存测试用例会是一种比较方便和熟悉的方式。但 postman 本身是一个图形化软件,相对较难或较麻烦(如使用 …

php json -gt;访问,【转】Php+ajax+jsonp解决ajax跨域问题

首先:jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。发送端:$.ajax({type : "post",url : "ajax.php",dataType : "jsonp",jsonp: "callback",//传递给请求处理程序或页面的&…

《看聊天记录都学不会Python到游戏实战?太菜了吧》(1)加载Python神器!亮剑!

本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新,包括别的语言以及实战都将使用对话的方式进行教学,基础编程语言教学适用于零基础小白,之后实战课程也将会逐步更新。 若…

Codeigniter 3 拓展HMVC

2019独角兽企业重金招聘Python工程师标准>>> 在Codeiniter(以下统称CI) 2.X版本中,我们就通过拓展核心类库实现了HMVC,但是同样的代码,拿到CI 3中,就很有可能不好用了。 ###拓展核心类库方式 官…

玩转ASP.NET Core 6.0框架-序言

ASP.NET Core是微软提供的强大的web框架,它有很多潜在的强大而有用的功能。本专栏的目标是帮助您把框架的隐藏能力最大限度地发挥出来,让您能够按需定制ASP NET Core框架。本专栏提供了一种具体的操作和实现方法,可以让你在短时间尽可能地提高…

从C#开始的面向对象编程经典自学教程

1、C语言的时代 在C语言时代,可以认为那时的编程过程就是表格加工过程,也就是从A表格到B表格、再到C表格…..等等,这个过程中,计算机语言如何描述一个表格,成为计算机语言的关键。 对一个表格的分析可以发现:表格是两部分组成:表头和表格: 学生表 STUDENT 在这个表格…

《看聊天记录都学不会Python到游戏实战?太菜了吧》(2)在python中加号竟然如此善变

本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新,包括别的语言以及实战都将使用对话的方式进行教学,基础编程语言教学适用于零基础小白,之后实战课程也将会逐步更新。 若…

mysql数据库rp集群,使用MySQL-Cluster搭建MySQL数据库集群

1、MySQL集群的作用:- 解决访问节点的单点故障- 数据存储节点的单点故障- 解决数据存储节点数据备份问题2、集群:使用一组服务器提供相同的服务3、关于MySQL-Cluster:MySQL官方提供的集群版本已集成标准版MySQL程序,可独立安装使用…

桌面虚拟化云技术将支撑数字化医院

桌面虚拟化云技术将支撑数字化医院 2013-12-04 10:32 现今医疗行业已经从医院——患者的二元关系走向从医院——患者——政府监督——医疗保险的多元关系,医疗体系需要更高效的运转,患者需要更好的就医体验,这使得医疗行业信息化建设的重要性…

《看聊天记录都学不会C语言?太菜了吧》(14)这么神奇?我写了20行代码竟然一行就可以搞定?

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我,若你是真心学习可以送你书籍,指导你学习,给予你目标方向的学习路线,无套路,博客为证。 本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖…

【经典回放】多种语言系列数据结构算法:栈(C#版)

本文采用C#语言实现栈结构算法并举例应用。 一、C#的栈对象使用 对C#而言,要使用栈是极其简单的事情,因为C#已经有栈对象,所以根本不需要自用再用顺序表构造栈,只需要你会说明、会应用即可。 在C#中栈对象的类型名称是Stack,这是个泛型的对象,所以,你在使用这个对象的时…

在 Kubernetes 上部署 Secret 加密系统 Vault

HashiCorp Vault 是一个基于身份的 Secret 和加密管理系统。Secret 是您想要严格控制访问的内容,例如 API 加密密钥、密码或证书。Vault 提供由身份验证和授权方法控制的加密服务。使用 Vault 的 UI、CLI 或 HTTP API,可以安全地存储和管理对机密和其他敏…

《看聊天记录都学不会C语言?太菜了吧》(15)你学了一节课的函数我5分钟搞定了,还很熟

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我,若你是真心学习可以送你书籍,指导你学习,给予你目标方向的学习路线,无套路,博客为证。 本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖…

【经典回放】多种语言系列数据结构算法:栈(JavaScript版)

本文采用JavaScript语言实现栈结构算法并举例应用。 JavaScript的栈是数组对象中自动提供的,这点如同C#,实际也不需要自己编写什么栈的程序,如果你用: var s=new Array(); 定义一个s的数组,则这个s上将有以下的方法可供使用: 其中:FF: Firefox, IE: Internet Explore…

设计模式(10)-----模板方法模式

模板方法模式(Template Method) 定义 定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 UML类图 例子 AbstractClass package com.csdhsm.pattemdesign.template;/** * Title: …

SLES修改本地FTP安装源

2019独角兽企业重金招聘Python工程师标准>>> SLES修改本地FTP安装源 一、配置本机FTP............................................................................................................. 1 1.1、安装.............................................…

.NET7 Preview4:重构的返回值TypedResults

为了更好的测试,更好的性能,Preview4带了一个新的请求返回值类型,这个新的类型中封装了所有的Http请求返回状态函数,还包括了返回成功后的几种数据类型,下面列举了几个常用的类型:app.MapGet("/test_o…

MATLAB软件禁用利好,Matlab被禁用?一款国产软件站了出来说:我就是中国的Matlab...

众所周知,前段时间Matlab被禁用,引发了网友们对于国产工业软件落后的诸多思考,比如为什么落后,落后到什么程度,有没有替代品等等。并且从Matlab到EDA,再到CAD等等,甚至工业操作系统等等&#xf…