【Android】 ClassLoader 知识点提炼

1.Java中的 ClassLoader

1.1 、ClassLoader的类型

        Java 中的类加载器主要有两种类型,即系统类加载器和自定义类加载器。其中系统类
加载器包括3种,分别是 Bootstrap ClassLoader、Extensions ClassLoader 和 Application
ClassLoader。

1.1.1.Bootstrap ClassLoader (引导类加载器)

        C/C++代码实现的加载器,用于加载指定的JDK的核心类库,比如java.lang、java.uti.等这些系统类。它用来加载以下目录中的类库:

  • $JAVA_HOME/jre/lib目录
  • -Xbootclasspath 参数指定的目录

        Java虚拟机的启动就是通过 Bootstrap ClassLoader 创建一个初始类来完成的。由于Bootstrap ClassLoader 是使用 C/C++语言实现的,所以该加载器不能被 Java代码访问到。 

1.1.2.Extensions ClassLoader(拓展类加载器) 

        Java 中的实现类为 ExtClassLoader,因此可以简称为 ExtClassLoader,它用于加载Java的拓展类,提供除了系统类之外的额外功能。ExtClassLoader 用来加载以下目录中的类库:

  • 加载$JAVA_HOME/jre/lib/ext目录
  • 系统属性java.ext.dir 所指定的目录

1.1.3.Application ClassLoader (应用程序类加载器)

        Java 中的实现类为AppClassLoader,因此可以简称为 AppClassLoader,同时它又可以称作 System ClassLoader (系统类加载器),这是因为AppClassLoader 可以通过 ClassLoader的getSystemClassLoader 方法获取到。它用来加载以下目录中的类库:

  • 当前程序的Classpath目录。
  • 系统属性java.classpath 指定的目录。

1.1.4.Custom ClassLoader (自定义类加载器)

        除了系统提供的类加载器,还可以自定义类加载器,自定义类加载器通过继承java.lang.ClassLoader 类的方式来实现自己的类加载器,Extensions ClassLoader 和 App
ClassLoader也继承了java.lang.ClassLoader 类。

1.1.5.ClassLoader 继承关系图

2.Android中的 ClassLoader 

2.1. ClassLoader的类型

        Java 中的 ClassLoader 可以加载jar 文件和 Class 文件 (本质是加载CIass文件),这一点在Android中并不适用,因为无论是 DVM还是ART,它们加载的不再是 Class文件,而是 dex 文件。

        Android 中的 ClassLoader 类型和Java 中的ClassLoader 类型类似,也分为两种类型
分别是系统类加载器和自定义加载器。其中系统类加载器主要包括 3 种,分别是
BootClassLoader、 PathClassLoader 和 DexClassLoader。

2.1.1. BootClassLoader

        Android 系统启动时会使用 BootClassLoader 来预加载常用类,与SDK 中的 Bootstrap
ClassLoader 不同,它并不是由 C/C++代码实现的,而是由 Java 实现的。

2.1.2. DexClassLoader

        DexClassLoader 可以加载 dex 文件以及包含 dex的压缩文件(apk 和jar 文件)不管加
载哪种文件,最终都要加载 dex 文件。

2.1.3. PathClassLoader

        Android 系统使用 PathClassLoader 来加载系统类和应用程序的类。PathClassLoader
默认了参数 optimizedDirectory 的值为/data/dalvik-cache,很显然 PathClassLoader 无法
定义解压的dex文件存储路径,因此 PathClassLoader 通常用来加载已经安装的apk的dex
文件(安装的apk的dex 文件会存储在/data/dalvik-cache 中)。

2.1.4. ClassLoader 继承关系图

  • ClassLoader 是一个抽象类,其中定义了 ClassLoader 的主要功能。BootClassLoader是它的内部类。
  • SecureClassLoader 类和JDK8中的 SecureClassLoader 类的代码是一样的,它继承了抽象类 ClassLoader。SecureClassLoader 并不是 CassLoader 的实现类,而是拓展了ClassLoader类加人了权限方面的功能,加强了ClassLoader 的安全性。
  • URLClassLoader 类和JDK8中的URLCIssLoader 类的代码是一样的,它继承自SecureClassLoader,用来通过URL路径从jar 文件和文件夹中加载类和资源。
  • InMemoryDexClassLoader 是 Android 8.0新增的类加载器,继承自BaseDexClassLoader,用于加载内存中的dex 文件。
  • BaseDexClassLoader 继承自 ClassLoader,是抽象类 ClassLoader 的具体实现类PathClassLoader、DexClassLoader 和InMemoryDexClassLoader 都继承自它。

2.2 ClassLoader的加载过程

2.2.1. BootClassLoader的加载过程

         BootClassLoader 是在 Zygote进程的 ZygoteInit的入口方法(main)中被创建的,用于加载preloaded-classes 文件中存有的预加载类。预加载属于拿空间换时间的策略,Zygote 环境配置得越健全越通用,应用程序进程需要单独做的事情也就越少,预加载除了预加载类,还有预加载资源和预加载共享库。

一些预加载类如下图所示:

2.2.2. PathClassLoader的加载过程 

        PathClassLoader 是在SystemServer 进程中采用工厂模式创建的。

3.双亲委托模式

        类加载器查找 Class 所采用的是双亲委托模式,所谓双亲委托模式就是首先判断该Class 是否已经加载,如果没有则不是自身去查找而是委托给父加载器进行查找,这样依次进行递归,直到委托到最顶层的 Bootstrap ClassLoader,如果 Bootstrap ClassLoader 找到了该 Class,就会直接返回,如果没找到,则继续依次向下查找,如果还没找到则最后会交由自身去查找。

通俗的讲就是你要找一件玩具,你找不到就问你父亲有没有见过这个玩具(是否已经加载),你父亲没见过就问你父亲的父亲有没有见过,一直往上问,如果谁见过就把玩具找出来给你。如果最大的老父亲还是没见过他就帮你找,找不到他就歇下了叫儿子帮忙找,一直往下,找到就给你,没找到你就自己找。

4.Java中的ClassLoader与Android中ClassLoader的区别

  • Java的引导类加载器是由C++编写的,Android中的引导类加载器则是用Java编写的。
  • 由于Android 中加载的不再是 Class 文件,因此Android 中没有 ExtClassLoader和AppClassLoader,替代它们的是 PathClassLoader和 DexClassLoader。

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

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

相关文章

鸿蒙原生应用元服务开发-WebGL网页图形库开发无着色器绘制2D图形

无着色器绘制2D图形 使用WebGL开发时&#xff0c;为保证界面图形显示效果&#xff0c;请使用真机运行。 此场景为未使用WebGL绘制的2D图形&#xff08;CPU绘制非GPU绘制&#xff09;。开发示例如下&#xff1a; 1.创建页面布局。index.hml示例如下&#xff1a; <div class…

算法学习---栈和队列算法学习

一、用栈去实现队列 1.整理思路 栈的特点&#xff1a;先进后出 队列的特点&#xff1a;先进先出 我们要用栈的先进后出&#xff0c;来模拟实现队列的先进后出。我们需要借助两个栈去实现&#xff0c;分别叫做栈1和栈2。 栈1主要是用来存储数据的&#xff0c;我们将要插入的数据…

树莓派Python环境配置:删除Python 2、默认使用Python 3及配置Python镜像源指南

树莓派Python环境配置&#xff1a;优化升级三部曲 文章目录 树莓派Python环境配置&#xff1a;优化升级三部曲前言一、查看系统预装的python版本二、卸载python2并默认python3三、删除默认python3.7并升级到python3.9四、更换树莓派上的pip系统镜像源一键更换清华源&#xff08…

LoadRunner学习:RuntimeSetting、参数化、关联、(unfinished

LoadRunner RuntimeSetting 运行时设置 在Vuser中设置Run-time Settings RunLogic&#xff1a;运行逻辑&#xff0c;决定了脚本真正执行逻辑&#xff0c; Init和End部分代码只能执行一次。决定脚本真正执行逻辑的意思是&#xff0c;在Run中的代码和Number of Iteration决定了…

灵魂指针,教给(三)

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 目录 一、 字符指针变量 二、数组指针变量 2.1 数组指针变量是什么 2.2 数组指针变量如何初始化 三、二维数组传参本质 四、函数…

Redis + Caffeine = 王炸!!

在高性能的服务架构设计中,缓存是一个不可或缺的环节。在实际的项目中,我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中,只有当缓存的访问没有命中时再查询数据库。在提升访问速度的同时,也能降低数据库的压力。 随着不断的发展,这一架构也产生了改进,在…

Selenium控制已运行的Edge和Chrome浏览器(详细启动步骤和bug记录)

文章目录 前期准备1. 浏览器开启远程控制指令&#xff08;1&#xff09;Edge&#xff08;2&#xff09;Chrome 2. 执行python代码&#xff08;1&#xff09;先启动浏览器后执行代码&#xff08;2&#xff09;通过代码启动浏览器 3. 爬取效果3. 完整代码共享3.1 包含Excel部分的…

【数据结构】初识二叉搜索树(Binary Search Tree)

文章目录 1. 二叉搜索树的概念2. 二叉搜索树的操作1.1 二叉搜索树的查找1.2 二叉搜索树的插入1.3 二叉搜索树的删除 1. 二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它可能是一棵空树&#xff0c;也可能是具有以下性质的二叉树&#xff1a; 若它的左子树不为空&am…

力扣L5----- 58. 最后一个单词的长度(2024年3月11日)

1.题目 2.知识点 注1&#xff1a; lastIndexOf()它用于查找指定字符或子字符串在当前字符串中最后一次出现的位置。它的作用是从字符串的末尾向前搜索指定字符或子字符串&#xff0c;并返回其最后一次出现的位置的索引。 &#xff08;1&#xff09;例如&#xff0c;在字符串 …

Rust入门:C++和Rust动态库(dll)的相互调用

无论是C调用Rust动态库还是Rust调用C动态库&#xff0c;其操作基本都是一样地简单&#xff0c;基本和C调用C的动态库没什么区别&#xff0c;只需要列出所需要导入的函数&#xff0c;并链接到相应的lib文件即可。 这里&#xff0c;在windows中&#xff0c;我们以dll动态库为例说…

OpenCV学习笔记(一)——Anaconda下载和OpenCV的下载

OpenCV是图象识别中有巨大的应用场景&#xff0c;本篇文章以Python为基础。当初学OpenCV的时候&#xff0c;推使用在Anaconda编写代码&#xff0c;原因比较方便&#xff0c;下面我们对于Anaconda的下载过程进行演示。 Anaconda的下载 首先打开官网www.anaconda.com/download找…

数据结构---C语言栈队列

知识点&#xff1a; 栈&#xff1a; 只允许在一端进行插入或删除操作的线性表&#xff0c;先进后出LIFO 类似一摞书&#xff0c;按顺序拿&#xff0c;先放的书只能最后拿&#xff1b; 顺序栈&#xff1a;栈的顺序存储 typedef struct{Elemtype data[50];int top; }SqStack; SqS…

设计模式-行为型模式-模版方法模式

模板方法模式&#xff0c;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。[DP] 模板方法模式是通过把不变行为搬移到超类&#xff0c;去除子类中的重复代码来体现它的优势。 //首…

【Leetcode每日一题】 位运算 - 面试题 01.01. 判定字符是否唯一(难度⭐)(33)

1.题目解析 题目链接&#xff1a;面试题 01.01. 判定字符是否唯一 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于判断题目所给字符串是否存在相同字母&#xff0c;存在返回false即可&#xff0c;不存在返回true即可。 …

Caffeine缓存

本地缓存基于本地环境的内存&#xff0c;访问速度非常快&#xff0c;对于一些变更频率低、实时性要求低的数据&#xff0c;可以放在本地缓存中&#xff0c;提升访问速度 使用本地缓存能够减少和Redis类的远程缓存间的数据交互&#xff0c;减少网络 I/O 开销&#xff0c;降低这…

08 聚合函数

聚合函数 我们上一章讲到了 SQL 单行函数。实际上 SQL 函数还有一类&#xff0c;叫做聚合&#xff08;或聚集、分组&#xff09;函数&#xff0c;它是对一组数据进行汇总的函数&#xff0c;输入的是一组数据的集合&#xff0c;输出的是单个值。 1.聚合函数介绍 什么是聚合函…

for、while、do...while循环的使用

本篇文章只记录for、while、do...while循环的使用&#xff0c;由于java循环较为简单&#xff0c;所以直接上代码。 1、for循环 需求&#xff1a;循环遍历求和 1-100。 public class Demo {public static void main(String[] args) {int sum 0;for (int i 1; i < 100; i…

YOLOv5目标检测学习(4):YOLOV5源码的文件结构解析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言①py、cpp、java后缀的文件②md、txt、yml后缀的文件③yaml后缀的文件 一、.github文件夹1.1 workflows文件夹&#xff1a;该文件夹通常包含GitHub Actions 的工…

RHEL9 DNF/YUM仓库管理软件包

DNF/YUM仓库管理软件包 一个基于RPM包的软件包管理器能够从指定的服务器自动下载RPM包并且安装&#xff0c;自动处理依赖性关系&#xff0c;并且一次性安装所有依赖的软件包C/S模式 Server服务端提供RPM软件包与数据库文件repodataClient客户端使用dnf仓库 常用组合 组合参…

解决Klipper下位机ID获取失败问题

使用硬件&#xff1a; 上位机&#xff1a;必趣派&#xff0c;版本CB1_Debian11_Klipper_kernel5.16_20230303 下位机&#xff1a;八爪鱼STM32F407 问题&#xff1a;上位机获取下位机ID失败。 解决&#xff1a;咨询DIY群友&#xff0c;也对这个问题不太了解。我调试过程中&…