Android类加载机制简介

news2024/11/28 8:48:48

一、前言

随着 Android 技术的不断发展,对其内部机制的探索也日益深入。类加载机制作为 Android 运行时环境的核心组成部分之一,影响着应用的性能、安全性以及可扩展性。通过对 Android 类加载机制的研究,开发者可以更好地优化代码结构、提高应用的启动速度、解决潜在的安全问题,并实现更加灵活的功能扩展。

本文旨在对 Android 类加载机制进行简要介绍,帮助读者建立起对这一重要概念的初步认识,为进一步深入学习和实践 Android 开发奠定基础。

二、Android 类加载器的类型

在这里插入图片描述

2.1 BootClassLoader

  • 这是 Android 系统启动时使用的类加载器。它主要负责加载 Android 框架的核心类库,如 java.lang 和 android.* 等包中的类。
  • BootClassLoader 是由 C/C++ 代码实现的,在 Java 层无法直接获取到它的实例。

2.2 PathClassLoader

  • 用于加载系统类和应用程序的类。通常,它会从应用程序的安装目录下加载 dex 文件。
  • 在 Android 应用开发中,PathClassLoader 是比较常用的类加载器之一。它可以加载已经安装在设备上的应用程序的类文件。

2.3 DexClassLoader

  • 允许在运行时动态加载外部的 dex 文件或包含 dex 文件的 apk 文件。
  • 这使得开发者可以在应用程序运行时加载新的功能模块,实现插件化开发等高级功能。

三、类加载的过程

在这里插入图片描述

3.1 加载

  • 通过类的全限定名,找到对应的类文件,并将其读取到内存中。这个过程可能涉及从文件系统、网络或者其他存储介质中读取类文件。
  • 例如,当应用程序启动时,系统会通过类加载器加载应用程序的主类,从而启动应用程序的执行。

3.2 链接

  • 验证:检查加载的类文件的正确性和安全性,确保类文件符合 Java 虚拟机规范。例如,检查类文件的格式是否正确,常量池中的符号引用是否有效等。
  • 准备:为类的静态变量分配内存,并设置默认初始值。例如,对于静态 int 类型的变量,初始值为 0。
  • 解析:将类文件中的符号引用转换为直接引用。例如,将类文件中对其他类的引用转换为实际的内存地址。

3.3 初始化

  • 执行类的初始化代码,包括静态变量的赋值和静态代码块的执行。例如,在类的初始化代码中,可以进行一些初始化操作,如创建数据库连接、加载配置文件等。

四、Android类加载机制

4.1 双亲委派机制

在这里插入图片描述

4.1.1举例说明

调用 DexClassLoader 进行类加载 类A 时 , 进行如下操作 :

① DexClassLoader 查询 : 查询自己是否加载过 A ;

  • 如果加载过则不需要再进行加载 ;
  • 如果没有加载过 , 则向上级 PathClassLoader 询问 是否有加载过 A ;

② PathClassLoader 查询 : 查询自己是否加载过 A ;

  • 如果加载过则不需要再进行加载 ;
  • 如果没有加载过 , 则向上级 BootClassLoader 询问 是否有加载过 A ;

③ BootClassLoader 查询 : 查询自己是否加载过 A ;

  • 如果加载过则不需要再进行加载 ;
  • 如果没有加载过 , 则 查询自己是否可以加载 ;

④ BootClassLoader 查询是否可以加载 :

  • 如果自己可以加载 A , 则自己加载 ;
  • 如果自己不可以加载 A , 则将加载任务委派给下级 PathClassLoader ;

⑤ PathClassLoader 查询是否可以加载 :

  • 如果自己可以加载 A , 则自己加载 ;
  • 如果自己不可以加载 A , 则将加载任务 委派给下级 DexClassLoader ;

⑥ DexClassLoader 查询是否可以加载 :

  • 如果自己可以加载 A , 则自己加载 ;
  • 如果自己不可以加载 A , 则 抛出 Class Not Found 异常 ;

整个过程就是 从下到上 询问 , 然后 从上到下 委派

4.1.2 双亲委派机制的作用

4.1.2.1保证类的唯一性
  • 由于父类加载器优先加载类,这样可以避免同一个类被多个不同的类加载器重复加载,从而保证了类在 JVM(在 Android 中是 ART 虚拟机或 Dalvik 虚拟机)中的唯一性。
  • 例如,如果应用程序中的某个类与系统类库中的类同名,如果没有双亲委派机制,那么可能会加载两个不同的类,导致程序出现错误。
4.1.2.2提高安全性
  • 双亲委派机制可以确保系统类由系统类加载器加载,而应用程序的类由应用程序类加载器加载。这样可以防止恶意代码通过自定义类加载器加载系统类,从而提高了系统的安全性。
  • 例如,如果恶意代码试图加载一个伪装成系统类的恶意类,由于双亲委派机制,系统类会优先由系统类加载器加载,从而阻止了恶意代码的加载。
4.1.2.3保证类的加载顺序
  • 双亲委派机制规定了类的加载顺序,即先由父类加载器加载,父类加载器无法加载时才由子类加载器加载。这样可以保证类的加载顺序符合预期,避免因类加载顺序不当而导致的错误。
  • 例如,如果一个类依赖于另一个类,那么在加载这个类之前,必须先加载它所依赖的类。双亲委派机制可以确保这种依赖关系得到正确的处理。

4.2 类加载机制的作用

4.2.1 实现代码的动态加载

  • 通过 DexClassLoader,可以在应用程序运行时动态加载外部的 dex 文件或 apk 文件,实现插件化开发。这使得应用程序可以在不重新安装的情况下,增加新的功能模块。
  • 例如,一些游戏应用可以通过动态加载插件的方式,为玩家提供新的游戏关卡和道具。

4.2.2 提高应用程序的安全性

  • 类加载机制可以对加载的类文件进行验证,确保类文件的正确性和安全性。这可以防止恶意代码的注入和攻击。
  • 例如,Android 系统通过类加载机制,对应用程序的安装包进行签名验证,确保应用程序来自可信的来源。

4.2.3 实现类的隔离

  • 不同的类加载器可以加载相同名称的类,但是这些类在内存中是相互隔离的。这使得不同的应用程序或者同一个应用程序的不同模块之间可以使用相同名称的类,而不会产生冲突。
  • 例如,在 Android 系统中,不同的应用程序使用不同的类加载器,从而实现了应用程序之间的类隔离。

五、拓展阅读

5.1 Android 类加载机制与 Java 类加载机制有何不同

对比属性Java 类加载机制Android 类加载机制
类加载器类型启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)、应用程序类加载器(Application ClassLoader)BootClassLoader、PathClassLoader、DexClassLoader
加载文件格式.class 文件经过优化的 dex 文件
运行环境服务器、桌面等资源相对丰富的环境移动设备,资源有限
类加载时机程序运行过程中首次使用该类时进行应用程序启动时进行大量类加载,也支持运行时动态加载
安全机制类加载器层次结构和安全管理器实现安全机制除类加载器隔离机制外,还有应用程序签名、权限管理等机制

5.2 Android 类加载机制的优缺点分别是什么?

方面优点缺点
灵活性可通过 DexClassLoader 实现插件化开发等高级功能,提高开发灵活性。复杂性较高,涉及多种类加载器和复杂加载过程,理解和掌握较难,易出现类加载相关问题。
资源管理加载类时进行优化,文件更紧凑,占用内存小,能合理管理内存和资源。动态加载类时存在一定性能开销,频繁动态加载可能影响应用性能和响应速度。
安全性通过应用程序签名、权限管理等机制确保安全性,类加载器层次结构提供安全隔离。/
适应环境针对移动设备资源有限性进行优化,能快速加载类,减少启动时间,提高用户体验。随着系统升级可能出现版本兼容性问题,开发者需关注系统更新并调整类加载策略。

5.3 Android 类加载机制的发展历程

时代类加载器类型类加载过程特点
Dalvik 时代BootClassLoader、PathClassLoader、DexClassLoader加载(找到 dex 文件并读入内存)、验证(检查格式和内容)、转换(将 Dalvik 字节码转换为机器码)、初始化(执行初始化代码)Dalvik 字节码经过优化占用内存小,适合移动设备,但性能相对低、启动时间长
ART 时代BootClassLoader、PathClassLoader、DexClassLoader加载(同 Dalvik)、验证(更严格)、编译(安装时或首次运行时将 dex 文件编译为本地机器码)、初始化(执行初始化代码)采用 AOT 和 JIT 编译结合提高性能和启动速度,支持多 dex 文件优化、运行时内存管理等高级特性
现代 Android优化后的 PathClassLoader、DexClassLoader 等,引入 InMemoryDexClassLoader 等类似 ART,不断优化效率和性能类加载器优化提高效率和性能,支持插件化开发,增强安全性

附录

【Java 虚拟机原理】Android 类加载机制 ( 双亲委派机制 | BootClassLoader | PathClassLoader | DexClassLoader )

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

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

相关文章

requests请求库入门使用

requests 库是一个功能强大且易于使用的 HTTP 请求库,适用于各种网络请求任务。它简化了 HTTP 请求的发送过程,并提供了丰富的功能来处理各种网络请求和响应。 1.安装 首先,你需要安装 requests 库。如果你还没有安装,可以使用 …

网优学习干货:2.6G仿真操作(1)

2.6G工程建立——整体仿真过程 针对覆盖仿真、速率仿真及蒙特卡洛仿真的说明 覆盖仿真:覆盖仿真主要用于评估网络覆盖性能。基于MassiveMIMO天线、射线传模或经验传模进行覆盖预测,计算链路损耗后,基于栅格分析估算小区覆盖预测的各项指标&am…

前端不同项目使用不同的node版本(Volta管理切换)

前端不同项目使用不同的node版本(Volta管理切换) 使用volta自动切换前端项目的node版本, 每个不同的前端项目,可以使用不同的node版本。Volta这个工具,它允许用户方便地安装、切换和管理不同版本的Node.js,避免了为每个项目手动配…

QT6聊天室项目 核心类与主窗口设计逻辑分析

核心类 核心类设计逻辑 数据结构设计(data.h) 用户信息 用户ID用户网名用户个人签名用户手机号码用户头像聊天会话信息 会话编号会话名称(单聊则是对方网名,群聊则是群名)最新消息会话图标(单聊对方头像&a…

sortable中el-table拖拽及点击箭头上下移动row

效果 安装 npm install sortablejs --save 引入 import Sortable from "sortablejs"; <el-table:data"tableBody"borderref"tableRef":stripe"true":key"tableKey"><el-table-column type"index" la…

driver.find_element 找不到元素的大坑

前端使用element框架。 登录进去使用开发人员工具能看到元素&#xff0c;复制xpath使用find_element死活找不到。 其中一次复制的xpath 注意红色部分: #先点击一下输入框 driver.find_element(By.XPATH,/html/body/div[1]/section/section/section/main/div/div[1]/div/form/…

迎接 Apple Intelligence.一:首次啟用

年 Apple 各平台的重點新功能&#xff0c;相信非 Apple Intelligence 莫屬。Apple 將會將人工智能整合到 iOS 18、iPadOS 18 和 macOS Squoia。在機械學習和大型語言模型加持下&#xff0c;預計 Siri 的對答會更加自然流暢&#xff0c;而且能直接提供答案&#xff0c;而不像過去…

作业8/21

client cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), socket(new QTcpSocket(this)) {ui->setupUi(this); // 设置 UI 界面// 控件初始状态设置为禁用&#xff0c;防止未连接…

储能系统---德业、禾迈、昱能产品布局及对比

一、公司介绍 德业、昱能、禾迈作为微逆行业的佼佼者&#xff0c;同样代表了中国制造行业的三种技术形态。 德业&#xff1a;代表传统制造行业&#xff0c;转型电力电子领域的代表。 昱能&#xff1a;代表海归人员回国创业&#xff0c;致力于技术本土化的代表。 禾迈&#…

socket 验证字符串是否是有效ip地址

import socketdef is_valid_ip(ip):try:# 尝试将字符串解析为IP地址socket.inet_aton(ip)return Trueexcept socket.error:return False# 测试 print(is_valid_ip("192.168.1.1")) # True print(is_valid_ip("256.256.256.256")) # False print(is_valid…

计算机存储原理——基础

文章目录 存储介质简介1. 光介质存储2. 磁介质存储3. flash(闪存) 硬盘存储原理磁盘组件磁盘是如何存储文件的磁盘的性能 存储接口与存储协议接口类型SCSISCSI的寻址方式windows下查看SCSI寻址 接口与总线与协议的对应关系cpu是如何控制存储的 文件系统常见的文件系统文件系统中…

《数据结构》顺序表+算法代码+动画演示-C语言版

目录 顺序表概念 顺序表初始化 顺序表销毁 顺序表尾插 顺序表尾删 顺序表头删 顺序表头插 顺序表pos位置插入 顺序表pos位置删除 顺序表全部代码如下&#xff1a; 顺序表概念 顺序表是用一段 物理地址连续 的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下…

「OC」CAShapeLayer和UIBezierPath —— 抽屉视图之中圆角cell的实现

「OC」CAShapeLayer和UIBezierPath —— 抽屉视图之中圆角cell的实现 文章目录 「OC」CAShapeLayer和UIBezierPath —— 抽屉视图之中圆角cell的实现前言CALayer的子类CAShapeLayerpath 贝塞尔曲线应用实践参考资料 前言 上次我们学习了CALayer的相关知识 &#xff0c;但好像忘…

2024计算机软考报名流程(电脑报名)

1.24年下半年软考报名时间&#xff0c;各省报名时间不一样&#xff0c; 报名时间大概集中在&#xff1a;24年8月19日&#xff5e;24年9月15日&#xff1b; 报名网站&#xff1a;中国计算机技术职业资格网&#xff1b; 广东&#xff1a;2024年8月21日9:00至29日17:00 安徽&#…

全面调研:19类AI Agent框架的对比与分析

代理&#xff08;Agent&#xff09;指能自主感知环境并采取行动实现目标的智能体&#xff0c;即AI作为一个人或一个组织的代表&#xff0c;进行某种特定行为和交易&#xff0c;降低一个人或组织的工作复杂程度&#xff0c;减少工作量和沟通成本。 背景 目前&#xff0c;我们在…

监听页面滚动到某个元素 设置入场动画

mounted() {this.eventScroll()}, eventScroll() {// 选择你想要监听的元素const targetLogo document.getElementById(logoanimation);// 创建并配置IntersectionObserverconst observer new IntersectionObserver((entries) > {entries.forEach(entry > {if (entry.…

回收站的文件删除了怎么恢复?4个技巧轻松找回文件!

在日常使用电脑的过程中&#xff0c;回收站作为我们删除文件的临时存放地&#xff0c;扮演着重要的角色。然而&#xff0c;有时我们可能会不小心从回收站中删除了重要文件&#xff0c;导致数据丢失。面对这种情况&#xff0c;许多用户会感到焦虑和无助。但别担心&#xff0c;本…

基于Spark实现大数据量的Node2Vec

基于Spark实现大数据量的Node2Vec Node2Vec 是一种基于图的学习算法&#xff0c;用于生成图中节点的低维度、高质量的向量表示。这种算法基于 word2vec 模型&#xff0c;将自然语言处理中的词嵌入技术应用于图结构的节点&#xff0c;以捕捉节点之间的复杂关系。Node2Vec 特别强…

glibc 2.24 下 IO_FILE 的利用

文章目录 glibc 2.24 下 IO_FILE 的利用介绍&#xff1a;新的利用技术fileno 与缓冲区的相关利用实例&#xff1a;1. _IO_str_jumps -> overflow实例&#xff1a; 2. _IO_str_jumps -> finish实例: 最后拓展一下上一篇博客house of orange题目的做法: glibc 2.24 下 IO_F…

6.4K+ Star!一个强大的本地知识库问答系统,支持多格式文件和跨语言检索,为企业提供高效、安全的数据洞察……

https://github.com/netease-youdao/QAnything 【阅读原文】跳转Github项目 转自AIGC创想者 项目简介 QAnything 是一个基于本地知识库的问答系统&#xff0c;它能够理解和回答基于任何类型文件的问题。 QAnything支持的文件格式非常广泛&#xff0c;包括PDF、Word、PPT、XL…