【Android】Android类加载机制

news2024/10/7 17:23:30

ClassLoader介绍

任何一个 Java 程序都是由一个或多个 class 文件组成,在程序运行时,需要将 class 文件加载到 JVM 中才可以使用,负责加载这些 class 文件的就是 Java 的类加载机制。ClassLoader 的作用简单来说就是加载 class 文件,提供给程序运行时使用。每个 Class 对象的内部都有一个 classLoader 字段来标识自己是由哪个 ClassLoader 加载的。

Android 的类加载机制是基于 Java 的类加载机制,但在 Android 平台上有一些特殊的实现。

关键组件

BootClassLoader:

这是 Android 系统中的根类加载器,负责加载 Android 系统核心库。它是一个原生代码实现的类加载器,其加载路径在操作系统级别上提前配置好。(用于加载Android Framework层class文件)

PathClassLoader:

这是应用程序类加载器,负责加载应用程序的代码和资源。每个应用程序都有自己独立的 PathClassLoader 实例,用于加载应用程序 APK 中的类。(可以加载指定的dex,以及jar、zip、apk中的classes.dex)

DexClassLoader:

这是一个特殊的类加载器,用于加载未安装在应用程序目录下的 dex 文件。DexClassLoader 可以指定 dex 文件的路径,加载其中的类。(用于加载指定的dex,以及jar、zip、apk中的classes.dex)

在这里插入图片描述
PathClassLoader 与 DexClassLoader 的共同父类是 BaseDexClassLoader 。

在这里插入图片描述
可以看到两者唯一的区别在于:创建 DexClassLoader 需要传递一个 optimizedDirectory 参数,并且会将其创建为 File 对象传给 super ,而 PathClassLoader 则直接给到null。因此两者都可以加载指定的dex,以及jar、zip、apk中的classes.dex

PathClassLoader pathClassLoader = new PathClassLoader("/sdcard/xx.dex",getClassLoader());

File dexOutputDir = context.getCodeCacheDir();

DexClassLoader dexClassLoader = new DexClassLoader("/sdcard/xx.dex",dexOutputDir.getAbsolutePath(), null,getClassLoader());

其实, optimizedDirectory 参数就是dexopt的产出目录(odex)。那 PathClassLoader 创建时,这个目录为null,就意味着不进行dexopt?并不是, optimizedDirectory 为null时的默认路径为:/data/dalvik-cache。

在这里插入图片描述

双亲委托机制

Java

双亲委托机制(Parent Delegation Model)是 Java 类加载机制中的一种实现方式。它是一种层次化的类加载器结构,通过一种层级关系来管理和组织类的加载。

在双亲委托机制下,每个类加载器都有一个父类加载器(除了顶层的启动类加载器)。当一个类加载器需要加载某个类时,它首先将加载请求委托给父类加载器。只有当父类加载器无法加载该类时,子类加载器才会尝试加载。

具体的执行过程如下:

1.当一个类加载器收到加载请求时,它首先检查是否已经加载了这个类。如果已经加载,则直接返回已加载的类。

2.如果该类未被加载过,则将加载请求委托给其父类加载器。

3.父类加载器继续按照同样的规则进行加载:首先检查是否已经加载了这个类,然后委托给它的父类加载器。

这个委托的过程一直持续到达到最顶层的启动类加载器。如果启动类加载器仍无法加载这个类,则子类加载器开始尝试加载。

子类加载器尝试加载这个类,如果成功加载则返回,否则抛出 ClassNotFoundException 异常。

这种层级的双亲委托机制可以确保类的一致性和安全性。它的核心思想是优先使用高层次的父类加载器去加载类,这样可以避免重复加载和类的冲突。如果一个类已经被父类加载器加载了,那么子类加载器就不需要再加载,直接使用父类加载器加载的类即可。

Java 中的类加载器通常按照以下顺序进行委托:
启动类加载器(Bootstrap ClassLoader) ->
扩展类加载器(Extension ClassLoader) ->
应用程序类加载器(Application ClassLoader)。

开发者也可以自定义类加载器,并根据需要覆盖父类加载器的加载行为。

总的来说,双亲委托机制通过层级的类加载器结构,确保类的加载顺序和一致性,防止类的重复加载和冲突。它是 Java 类加载机制的一种重要实现方式,保证了 Java 程序的稳定性和安全性。

Android

在 Android 中,双亲委托机制采用了类似于 Java 的双亲委托模型,但在顶层类加载器的实现上有所不同。Android 的类加载器结构具体如下:(再来一遍)

BootClassLoader(引导类加载器):
这是 Android 系统中的根类加载器,负责加载核心库(例如核心 Java 类库和 Android 运行时库)。它是一个原生代码实现的类加载器,并且被固化在 Android 系统中,不允许应用程序开发者直接使用。

PathClassLoader(路径类加载器):
它是 Android 应用程序类加载器的最主要实现。每个应用程序都有自己独立的 PathClassLoader 实例,用于加载应用程序 APK 中的类和资源。该加载器会搜索应用程序的 APK 文件路径,并加载其中的类。

DexClassLoader(DEX 类加载器):
这是一种特殊的类加载器,可用于加载未安装在应用程序目录下的 DEX 文件。通过指定 DEX 文件的路径,可以加载其中的类。

Android 的类加载器在加载类时会按照以下顺序进行委托:

1.PathClassLoader 首先尝试加载类。如果它无法找到或加载请求的类,它会将加载请求委托给其父类加载器 BootClassLoader。
2.BootClassLoader 会继续尝试加载类。如果它仍然无法找到或加载请求的类,它会引发 ClassNotFoundException。

在 Android 应用程序中,PathClassLoader 是最常用的类加载器。它负责加载应用程序的代码和资源,包括 APK 文件中的 Java 类、独立库(如 .so 文件)和其他资产。PathClassLoader 沿着类路径搜索并加载类,如果找不到类,则委托给父类加载器进行加载。

通过双亲委托机制,Android 的类加载器确保了类的唯一性和一致性。如果一个类已经被父类加载器加载了,子类加载器就不会再次加载该类,直接使用已加载的类实例。这样可以避免重复加载和类的冲突

需要注意的是,为了适应 Android 运行环境,Android 的类加载器做了一些特殊处理。例如,在加载资源时,可以使用 Context 类提供的 getResources() 方法加载资源并返回一个由 PathClassLoader 加载的资源对象。

总结起来,Android 的双亲委托机制通过类加载器的层级关系,确保了类的加载顺序和一致性。PathClassLoader 是主要的应用程序类加载器,负责加载 APK 文件中的类和资源。BootClassLoader 是根类加载器,负责加载核心库。该机制保证了 Android 应用程序的稳定性和安全性。

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

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

相关文章

echarts图表-实现中国地图的绘制

第一步:引入中国地图的json数据,初始化echarts的dom结构,使用registerMap方法加载地图数据(注:echarts5.X版本后删除了中国地图的JSON,需自行下载JSON或降低echarts版本) 第二步:传输…

React通过props的children实现插槽功能

可能会比较遗憾的说 React中并没有vue中的 slot 插槽概念 不过 可以通过props.children 实现类似功能 我们先创建一个React项目 在src下创建目录components 在下面创建一个dom.jsx组件 参考代码如下 import React from "react" export default class dom extends R…

Android学习日志 一、滚动视图的嵌套

文章目录 滚动视图的嵌套创建项目(前期准备)工程搭建编写XML正式代码 By-Round Moon 滚动视图的嵌套 说明:本博客是博主学习安卓开发的第一个案例。接下来会进行一系列的样例,含很多基础部分,各位观众老爷请见谅。 Android Studio 版本:2022.2.1 patch …

如何将MBR转为GUID?这方法易于使用且安全!

为什么要将MBR转为GUID(GPT)? MBR代表主引导记录,它使用Legacy BIOS分区表。而GPT磁盘,也就是GUID分区表的缩写,是一种引入了统一可扩展固件接口 (UEFI) 的新布局。GPT磁盘有2个主要优势: GPT磁盘每个分区…

前端-CSS 字体和文本样式

字体大小 /* 浏览器默认字体大小 16px */ font-size: 16px;<div style"font-size: 16px;">Hello World!</div> <div style"font-size: 26px;">Hello World!</div>字体粗细 font-weight: 400;<div style"font-weight: no…

JumpServer开源堡垒机页面配置

JumpServer开源堡垒机页面配置 一、登录二、功能模块2.1、控制台2.1.1、用户管理2.1.1.1、用户列表2.1.1.2、用户组 2.1.2、资产管理2.1.2.1、资产列表2.1.2.1.1、创建服务器链接2.1.2.1.2、创建数据库MySQL链接 2.1.2.2、网域列表2.1.2.3、平台列表2.1.2.4、标签列表 2.1.3、账…

同源建模MOE:请叫我永远的神!

同源建模 实/操/篇 1.分子力场的设置 MOE中缺省的分子力场MMFF94x是一个用于小分子和复合物模拟的力场,不能很好地适用于大分子模拟,由于这里我们要进行同源模建,模拟对象是蛋白质结构,因此首先要将缺省分子力场MMFF94x更改为适用于蛋白质模拟的相关分子力场&#xff0c;如A…

【PCL】Ouster 和 Velodyne 激光雷达的 PCL 点云数据格式

【PCL】Ouster 和 Velodyne 激光雷达的 PCL 点云数据格式 0 news1 Ouster2 Velodyne3 数据类型转换 0 news Ouster 和 Velodyne 两公司合并。 1 Ouster GitHub: Link namespace ouster_ros {struct EIGEN_ALIGN16 Point {PCL_ADD_POINT4D;float intensity;uint32_t t;uint16_t…

conda 根目录内存满,更换新的目录

默认conda环境是在根目录&#xff0c;只需修改默认的目录即可 1 修改.condarc文件 vim ~/.condarc# 添加一行即可 envs_dirs:- /disk3/miniconda_envs/envs2 验证 创建一个conda环境 查看创建的路径 conda env list 这样以后都换把相关创建的包安装在disk3下&#xff0c;缓…

C++ - 20230630

一 . 思维导图 二. #include <iostream> using namespace std;class Person { private:int age;int p; public://无参构造Person(){age 0;p 0;}//有参构造Person(int age,int p):age(age), p(p){}//拷贝构造函数Person(Person &other) {this->age other.age;t…

《移动互联网技术》第九章 感知与多媒体: 了解质感设计的基本原则和设计方法

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Tomcat 部署优化

目录 一.Tomcat介绍 二.了解Tomcat里面里面是放什么的 三. Tomcat&#xff1a;是一个特殊的服务 有两个领域 四.tomcat概述 五.再加上那个扩展java虚拟机&#xff08;JVM&#xff09; 调优 tomcat 优化分两种 六.Tomcat核心组件 ​编辑 容器&#xff1a;什么是容器 …

Dart语法01-变量、内置类型、操作符、方法与异常

Dart基础 文章目录 Dart基础变量final与const 内置的类型Numbers&#xff08;数值&#xff09;Strings&#xff08;字符串&#xff09;Booleans&#xff08;布尔值&#xff09;Lists&#xff08;列表&#xff09;Maps&#xff08;映射集合&#xff09;Runes&#xff08;用于在字…

用八叉树检测点云是否发生变化

检测点云数据集之间的空间变化有以下几个用处&#xff1a; 目标跟踪与物体识别&#xff1a;空间变化检测可以用于实时更新点云数据中的物体位置、姿态、形状等信息。这对于目标跟踪和物体识别非常重要&#xff0c;可以帮助我们在动态场景中准确地识别和跟踪物体&#xff0c;从而…

Maven下载安装及其配置

Maven下载安装及其配置 文章目录 Maven下载安装及其配置1、Maven介绍2、Maven下载安装2.1、最新2.2、旧版3.8 3、Maven环境配置3.1、配置3.2、验证3.3、 配置本地仓库 4、Maven使用4.1、Maven常用命令4.2、IDEA中的使用 1、Maven介绍 Maven 是一个流行的构建工具和依赖管理工具…

使用Excel和PowerPoint设计24小时甘特图

1.前期调研 可以使用Project软件、在线甘特图MindsUP等来设计&#xff0c;可是我的需求是记录周边几个单位每天的开闭馆时间&#xff0c;而不是按照天、月等来记录项目周期。因此&#xff0c;这些软件不符合我的需求&#xff0c;必须用excel来设计。 2.excel录入数据 &#xf…

云时代已至,新一代数据分析平台是如何实现的?

2023 年 5 月&#xff0c;由 Stackoverflow 发起的 2023 年度开发者调查数据显示&#xff0c;PostgreSQL 已经超越 MySQL 位居第一&#xff0c;成为开发人员首选。PostgreSQL 在国内的热度也越来越高。6 月 17 日&#xff0c;PostgreSQL 数据库技术峰会在成都顺利召开。本次大会…

深入理解 Golang: 锁

本文通过对 Go 中源码层面的加锁、解锁实现细则来介绍锁的操作&#xff0c;包括 Mutex 互斥锁、RWMutex 读写锁&#xff0c;以及它们底层依赖的 sema 信号锁。 atomic 原子操作 正常情况下&#xff0c;多个协程同时操作 num 时&#xff0c;不能保证 num 值得最终一致性&#x…

锈湖新作地铁繁花试玩版正式上线啦

地铁繁花是锈湖厂商新作点击式解谜冒险解谜游戏&#xff0c;英文名称为“Underground Blossom”&#xff0c;在游戏中你将深入锈湖的地下&#xff0c;扮演并追溯Laura Vanderboom的人生和记忆吧&#xff01;从一个车站到另一个车站&#xff0c;每个地铁站都象征着劳拉的一段过去…

语音芯片WT2003H-B003,集成压力传感与语音提示的按摩器创新方案

​在如今追求健康、舒适生活方式的时代&#xff0c;压力传感技术与语音提示功能的结合正引领着按摩器行业的创新浪潮。WT2003H-B003语音芯片IC作为一款独具价值的语音芯片&#xff0c;以其集成了先进的压力传感算法和语音提示功能&#xff0c;为按摩器压感方案带来了全新的体验…