[Android] Android架构体系(1)

文章目录

  • Android 的框架
  • Dalvik 虚拟机
  • JNI
  • 原生二进制可执行文件
    • Android NDK中的binutils
  • Bionic
    • 谷歌考虑到的版权问题
    • Bionic与传统的C标准库(如glibc)的一些不同
  • 参考

Android 的框架

Android 取得成功的关键因素之一就是它丰富的框架集。

没有这些框架,Android 可能会和其他一些嵌入式 Linux 发布版本一样混得很差。

通过提供各种框架,Android 让应用可以很方便地创建进程,允许开发者使用高级的 Java 语言而不是底层的 C/C++语言进行编程。各种框架的不断增加也在进一步强化这一过程,因为有大量的用于进行图形、音频和硬件访问的API可供开发者使用。

使用 Java 的包命名规则后,Android 的框架会根据它们各自不同的功能被分割在各自不同的命名空间(namespace)中。位于命名空间 android.*中的包是可以供开发者使用的,而位于com.android.* 中的包则是仅供系统内部使用的。

Android 也支持大多数位于命名空间java*中的标准Java 运行时包。

Android 使用的所有框架都是被打包在设备的/system/framework 目录下的数个Java格式的*.jar 文件中的,而在 L版中则是被预编译进 boot.jar 文件中的。

尽管 AOSP 是开源的,但直接从JAR文件中找出相关的包也非常容易-只要调用 dexdump (或者dextra 工具)直接分析JAR
文件中的 classes.dex 文件就行了。

Dalvik 虚拟机

Android 对 Linux 另一个值得注意的扩展就是引入了 Dalvik 虚拟机。

Dalvik 虚拟机是让Android 能够在256M 内存就已经算“很大”了的移动设备中正常工作的关键因素。Dalvik 并不是第一种试图能够运行在移动设备上的虚拟机,Sun 公司的 Microsystems 曾经被认为有望能够压过 Java 2移动版(J2ME)一头,但实际上收效甚微。
Dalvik 主要是由 Dan Bornstein 发明的一一他2008 年在谷歌I/0大会上的演讲被认为是了解Dalvik 虚拟机设计的一份很重要的参考资料。

虚拟机的名字 (Dalvik) 是为了纪念冰岛北部的一个小渔村。

Dalvik 虚拟机尽管看上去和 Java 是等价的,但实际上并不是一个Java 虚拟机。虽然偏离得并不是很远,但它运行的是一种完全不同形式的字节码(这种字节码叫作 DEX,也就是“Dalvik EXecutable”的缩写),而且相对于 Sun/Oracle 设计的JVM,它在执行效率和共享内存方面做了更多的优化。这些优化使得它在受到严格限制的移动平台上占尽优势一这一点也正是 Java(特别是 J2ME)没法在有限的实现之外进一步获得增长的原因。

Android 选择Apache 的 Harmony 文件的一个子集作为它的核心类(core class)的基础。之所以选择 Harmony 是因为它是免费的(在 Apache 许可协议下)(原来是 Sun 的,现在是 Oracle的)JVM 的开源克隆体。Oracle 于 2010 年将谷歌告上了法庭,理由就是谷歌从未正确地获得Java 类库的使用授权,这场旷日持久的官司甚至直到 2015 年初还没有了结。

Dalvik 虚拟机正在被ART (Android 运行时,Android RunTime)逐步取代。但是这并不意味着 Dalvik 正在走向消亡。因为 Dalvik 只有在即时编译 (JIT,Just-In-Time compilation)方面的部分会被取代,而它使用的(DEX)文件格式作为至关重要的体系结构概念,仍是非常有生命力的。

JNI

Android 应用是运行在虚拟机里的,但有时,通常是在需要访问硬件或其他设备 (或芯片集)特有的功能时,它还是需要执行虚拟机之外的代码的。

所以 Dalvik 允许应用通过 JavaNative Interface(JNI)使用原生代码库(ELF 共享库)中的代码。

从某种程度上说,Android 对JNI是又爱又恨。厂商们无疑更青睐于“纯”Dalvik 的应用。

因为所有的代码都是运行在虚拟机里的,所以不会受到虚拟机/操作系统是运行在什么体系结构的处理器上的影响。

在这种情况下,Android 应用可以在无须任何修改的情况下运行在任意一个平台上,无论是 Intel、ARM、MIPS 还是其他什么处理器上。

但是另一方面,虚拟机环境也并非没有限制(特别是在开发者非常关心图形处理问题时) 和缺陷(特别是它很容易被反编译)。因此在应用中使用JNI以优化性能或对抗逆向工程的情况也是屡见不鲜的。

有鉴于此,谷歌也提供了使开发者能够生成原生库 (及二进制可执行程序)的原生代码开发包(NDK,NativeDevelopment Kit)。

我们打开APK文件,常常可以看到对应的动态库.so 或者静态库.a:
在这里插入图片描述

并非所有的应用中都使用了 JNI,但在那些使用了 JNI的应用中,我们也可以很方便地在安装包 (.apk
文件)中找到JNI库,因为它们是被放在一个单独的文件夹 “/lb/architecture中的。

原生二进制可执行文件

从 Linux 的角度讲,所有的可执行文件都是 ELF 二进制可执行文件。

Android 中的关键系统组件都是用 C/C++编写,并被编译成原生的二进制可执行文件的。而用户的应用则是编译成Dalvik 字节码的,但字节码是运行在 Dalvik 虚拟机的上下文环境中的(或者在 ART 中,是在运行之前被编译成原生代码的)。

而 Dalvik 虚拟机本身也是一个ELF格式的二进制可执行文件。因此,尽管大多数开发者大可以心安理得地忘掉“二进制可执行文件”这么一回事,但这些二进制可执行文件仍在Android 中扮演着重要的角色。

在Android中,二进制可执行文件通常都被放在/system/bin和/system/xbin这两个目录中(当然,还有一些重要的二进制可执行文件是放在/sbin 目录中的)。由于它们本身就是 AOSP 的一部分,所以无论是在哪种设备中,大多数的二进制可执行文件都是一样的。但是厂商或者芯片集的制造商往设备里添加一些额外的二进制可执行文件的情况也不少见。

我们可以随时执行 ps 命令,查看通过加载二进制可执行文件而运行起来的进程的列表。

在这里插入图片描述

因为ELF是个标准的文件格式,所以可以使用任何一种Linux ELF 文件解析工具(比如readelf、objdump或者其他 binutils 工具集中的工具) 分析 Android 的二进制可执行文件。

Android NDK在“toolchains/”目录中也提供了完整的工具集(使用交叉编译技术编译的,这些工具就能运行在移动设备上了)。

Android NDK中的binutils

在Android NDK中,binutils是一组二进制工具,用于处理和操作二进制文件,包括可执行文件和目标文件。以下是一些常见的Android NDK中的binutils工具:

  1. as(汇编器): 用于将汇编语言源代码转换成目标文件。
  2. ld(链接器): 用于将多个目标文件和库文件链接成一个可执行文件或共享库。
  3. objdump(目标文件转储工具): 用于获取目标文件的反汇编和其他有用的信息。
  4. strip(剥离工具): 用于从可执行文件或共享库中删除符号表和其他调试信息,以减小文件大小。
  5. readelf(ELF文件查看器): 用于查看和分析ELF(可执行和可链接格式)文件的内容和结构。

这些工具通过NDK中的bin目录提供,路径类似于:<NDK_DIR>/toolchains/<ARCH>/prebuilt/<HOST_PLATFORM>/bin/,其中<NDK_DIR>是NDK的根目录,<ARCH>是目标架构(例如arm、x86等),<HOST_PLATFORM>是宿主平台(例如windows、linux等)。

我们可以使用这些binutils工具来执行各种任务,如编译和链接原生代码,调试和分析二进制文件等。

Bionic

谷歌考虑到的版权问题

与Linux 发行版中使用GNU的LibC(GLibC作为它们的核心运行时(也就是著名的 libc.so)不同,Android选用了它自己的C运行时库一Bionic。

尽管谷歌宣称选择 Bionic 的理由主要是因为它的简洁性,但实际上合法性的考虑也占了很重要的位置。如果在 Android 中使用了使用GPL(GNU public license ,GNU 公共授权协议)授权的 GLibC,那么根据GPL,Android也就必须开源(这有点像 Linux 内核中使用GPL的情形),而这又是谷歌所要极力规避的。而Bionic 尽管也是开源的,但它混合使用了 BSD 授权协议(BSD 授权协议对使用相关软件的第三方软件的限制更少些) 和谷歌自己的授权协议。

Bionic与传统的C标准库(如glibc)的一些不同

Bionic是Android操作系统使用的C标准库。它是为了满足Android平台的需求而设计的,因此与传统的C标准库(如glibc)有一些区别。

Bionic库提供了一组API和功能,用于支持Android操作系统的核心功能,包括进程管理、内存管理、线程创建、文件操作等。Bionic库还对某些标准C库函数进行了优化和改进,以提高性能和适应Android系统的特定需求。

与传统的C标准库相比,Bionic库在以下方面有所不同:

  1. 大小和性能:Bionic库非常精简,旨在减小内存占用和优化启动速度。这对于移动设备这样的资源受限环境非常重要。
  2. 安全性:Bionic库在一些函数实现上有额外的安全保护,以防止缓冲区溢出和其他常见的安全漏洞。
  3. 兼容性:Bionic库与POSIX标准相对兼容,但在某些实现上存在细微差异。因此,一些传统的Linux应用程序可能需要针对Android做一些修改才能在Android平台上正常运行。

Bionic库是Android NDK的一部分,开发者可以使用NDK来编译和构建原生代码,并使用Bionic库提供的功能和API来开发Android应用程序的核心部分。

参考

《最强Android书:架构大剖析》

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Github 2024-01-16 Python开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-01-16统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目10HTML项目1 精心策划的Python资源列表 创建周期&#xff1a;3490 天开发语言&#xff1a;Python…

CTF CRYPTO 密码学-1

题目名称&#xff1a;enc 题目描述&#xff1a; 压缩包中含两个文件&#xff1a;一个秘钥d.dec&#xff0c;一个密文flag.enc 解题过程&#xff1a; Step1&#xff1a;这题是一个解密他题目&#xff0c;尝试openssl去ras解密 工具简介 在Kali Linux系统中&#xff0c;openss…

基于Java+SSM养老行动能力评估系统详细设计和实现【附源码】

基于JavaSSM养老行动能力评估系统详细设计和实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制…

关于git与git-lfs对文件压缩存储方面的研究

先说结论&#xff0c;git使用了Delta增量压缩算法&#xff0c;git-lfs实测没有进行任何压缩&#xff0c;这个结论让我很震惊。 测试过程如下&#xff1a; 测试git仓库自身的压缩 准备一个包含许多杂项文件的文件夹&#xff0c;大概几百M&#xff0c;要保证有一个txt文本文件…

深度好文:MySQL体系结构

MySQL采用的是客户/服务器体系结构&#xff0c;实际是有两个程序&#xff0c;一个是MySQL服务器程序&#xff0c;指的是mysqld程序&#xff0c;运行在存放数据库的机器上&#xff0c;负责在网络上监听并处理来自客户的服务请求&#xff0c;根据这些请求去访问数据库的内容&…

插件和工具汇总

插件和工具汇总 【一】MyBatis Log插件【二】热部署&#xff08;1&#xff09;适用于IntelliJ IDEA 2021.X以上版本&#xff08;2&#xff09;适用于IntelliJ IDEA 2021.X以下版本 【三】一些快捷键 【一】MyBatis Log插件 能够自动拼接参数生成执行的SQL语句&#xff0c;可以…

073:vue+mapbox 加载here地图(影像瓦片图 v3版)

第073个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载here地图的影像瓦片图。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共77行)相关API参考:专栏目标示例效果

docker:环境安装

系列文章目录 docker&#xff1a;环境安装 文章目录 系列文章目录前言一、Debian安装1.镜像下载2.VM安装3.Debian安装 二、docker安装1.Debian12换源2.docker安装3.docker测试4.docker换源 总结 前言 因为CentOS7确定停服时间为6月30日&#xff0c;虽然对我这种小虾米没啥影响…

ML:2-2-1 Tensorflow

文章目录 1. Tensorflow实现2. 模型训练细节2.1 定义模型f(x)2.2 找到loss and cost funciton2.3 Gradient descent 【吴恩达p60-61】 1. Tensorflow实现 继续看手写数字识别的例题第一步&#xff0c;我们上周学习了。第二步&#xff0c;让Tensorflow去编译模型。最重要的一步…

游戏素材永不缺,免费在线AI工具Scenario功能齐全,简单易用

Scenario是一个在线的AI驱动的工具&#xff0c;主要用于游戏艺术创作。它提供了一套全面的功能&#xff0c;旨在帮助游戏开发者创建与其独特风格和艺术方向相符的独特、高质量的游戏艺术。Scenario的突出特点之一是它的微调能力&#xff0c;允许用户根据独特的风格和艺术方向训…

Vue-23、Vue收集表单数据

1、效果 2、代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>收集表单数据</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist/vue.js…

Rust-Panic

什么是panic 在Rust中&#xff0c;有一类错误叫作panic。示例如下&#xff1a; 编译&#xff0c;没有错误&#xff0c;执行这段程序&#xff0c;输出为&#xff1a; 这种情况就引发了一个panic。在这段代码中&#xff0c;我们调用了Option::unwrap()方法&#xff0c;正是这个方…

小程序微信支付

微信支付介绍 支付大家应该都不陌生了&#xff0c;在现实生活中经常购买商品并且使用支付功能来付款&#xff0c;在付款的时候可能使用比较多的就是微信支付和支付宝支付了。在苍穹外卖项目中&#xff0c;选择的就是微信支付这种支付方式。 要实现微信支付就需要注册微信支付的…

Midjourney的注册、订阅

一、Midjourney是什么 MJ 就是一个人工智能绘图平台。它于2022年7月12日首次进行公测&#xff0c;2023年3月14日发布的 V5 版本&#xff0c;该版本较之前有了显著提升&#xff0c;生成图片分辨率更高&#xff0c;写实风格人物主体塑形更加准确&#xff0c;细节更多且审美在线。…

光伏逆变器数据采集方案

1 背景 分布式光伏电站主要建设在建筑屋面&#xff0c;厂房屋顶之上&#xff0c;电站后期的运维工作有诸多不便。运用光伏数据采集技术&#xff0c;对配套设备的数据进行远程采集&#xff0c;实现无人值守&#xff0c;可以降低运维成本&#xff0c;有效提高发电效率&#xff0…

Linux学习记录——사십삼 高级IO(4)--- Epoll型服务器(1)

文章目录 1、理解Epoll和对应接口2、简单实现 1、理解Epoll和对应接口 poll依然需要OS去遍历所有fd。一个进程去多个特定的文件中等待&#xff0c;只要有一个就绪&#xff0c;就使用select/poll系统调用&#xff0c;让操作系统把所有文件遍历一遍&#xff0c;哪些就绪就加上哪…

计算机网络-NAT网络地址转换

今天来回顾下之前所学的知识&#xff0c;将它们串联起来进行巩固。一开始了解了IP编址进行IP设置和划分网段&#xff1b;学习了二层以太网交换&#xff0c;了解了二层通信基础&#xff1b;学习了路由基础知识&#xff0c;大致了解到了路由是什么&#xff1f;静态路由和动态路由…

【QT】多窗体应用程序设计

目录 1主要的窗体类及其用途 2 窗体类重要特性的设置 2.1 setAttribute()函数 2.2 setWindowFlags()函数 2.3 setWindowState()函数 2.4 setWindowModality()函数 2.5 setWindowOpacity()函数 3 多窗口应用程序的设计 3.1 主窗口设计 3.2 QFormDoc类的设计 3.3 QFormDoc类的使用…

【Python_PySide6学习笔记(三十一)】基于PySide6实现自定义串口设备连接界面类:可实现串口连接断开、定时发送等功能

基于PySide6实现自定义串口设备连接界面类:可实现串口连接关闭、定时发送等功能 基于PySide6实现自定义串口设备连接界面类:可实现串口连接关闭、定时发送等功能前言一、界面布局二、串口相关功能实现三、完整代码四、调用方法五、实现效果基于PySide6实现自定义串口设备连接…

入门指南:使用STM32微控制器进行ADC数据采集

使用STM32微控制器进行ADC&#xff08;模数转换器&#xff09;数据采集是嵌入式系统开发中常见的任务。本文将介绍如何通过STM32CubeMX和HAL库函数进行ADC数据采集&#xff0c;并提供相应的代码示例。 1. STM32CubeMX配置 首先&#xff0c;使用STM32CubeMX工具配置STM32微控制…