另一角度看Android:Android 系统架构与 Linux 对比分析

2024-01-22 21:48

本文主要是介绍另一角度看Android:Android 系统架构与 Linux 对比分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

0x0 写在前面

Android 系统对我们快速进入移动互联网时代带来了卓越的贡献。其基于 Linux 开源而来,2005年8月由 Google 收购注资,2008年谷歌发布了第一款搭载安卓系统的智能手机,日后更加证明这一举动的深远影响。本文竭力避免网上论坛千篇一律的架构讲述,从另外一个不同的角度,带读者走进 Android 真实的架构之旅。

0x1 Android “伪”架构

不论是在 Google 官网,还是在各大社区论坛,如果你搜索 Android Architecture,即安卓架构,相信都会充斥着下面这张图,称其为 Android 架构图。实际上这是有一定的误区,我们后面再说。
在这里插入图片描述
Android 自顶向下依次划分为

  • Applications(应用层)
  • Application Framework(框架层)
  • Libraries & Android Runtime(库函数及安卓运行时)
  • HAL(硬件抽象层)
  • Linux Kernel(Linux内核层)

Applications 应用层,主要包含 Home(主界面)、联系人、电话以及浏览器等,这是普通用户通常可见的一层,也是最高的一层,通常所说的App,用户可见的多数服务也是在此层。

Application Framework 应用程序框架层,主要是用来支持各个应用的运行。实际上,各种应用提供给用户层面的,多数是一个界面,用户可以直接与其交互,比如点击某个按钮,这个时候,应用往往会调用框架层提供的服务,这才是真正提供应用功能的模块。比如上面图中的活动管理、电话管理器以及包管理器。

Labraries 系统库,提供了大量的程序在运行过程中需要的库,这些库往往是各种应用经常用到的,Android将其统一封装好,方便各个框架或者应用调用。系统库包括九个子系统,分别是Surface Manager图层管理、Media Manager媒体管理、SQLite小型数据库、OpenGLESate开放图形库用来支持3D效果、FreeType位图和矢量、WebKit浏览器内核、SGL 2D图形引擎库、SSL为数据通信提供支持、libc C语言的函数库

Android Runtime 安卓运行时,其实就是安卓与众不同的地方,即在Linux内核上,运行一个虚拟机,在虚拟机里再跑一个单独的应用,每个应用只能有一个唯一的虚拟机来承载。安卓运行时主要包括 core Labraries安卓开发核心库、DaLvik Virtual Machine Dalvik虚拟机。这里的库,主要是包括大多数Java语言需要调用的功能函数,以及Android核心库(anroid.os、.net、.media等)。而这里的虚拟机,不是普通的Java虚拟机(基于栈),而是一种基于寄存器的虚拟机,称之为 Dalvik虚拟机。

在这里插入图片描述

紧接着不是应该是内核层吗?其实不是。在内核和库函数之间,还有一个 HAL(Hardware Abstract Layer )层,即硬件抽象层。官网自动忽略了这个细节,可见其用意。

  • HAL屏蔽了不同硬件设备的差异,为Android提供了统一的访问硬件设备的接口。不同的硬件厂商遵循HAL标准来实现自己的硬件控制逻辑,但开发者不必关心不同硬件设备的差异,只需要按照HAL提供的标准接口访问硬件就可以了。
  • HAL层帮助硬件厂商隐藏了设备相关模块的核心细节。硬件厂商处于利益考虑,不希望公开硬件设备相关的实现细节;有了HAL层之后,他们可以把一些核心的算法之类的东西的实现放在HAL层,而HAL层位于用户空间,不属于linux内核,和android源码一样遵循的是Apache license协议,这个是可以开源或者不开的

最底层的是Linux内核。内核的作用就是提供各种驱动程序 Display Driver 显示驱动、Camra Driver 相机驱动、Bluetooth Driver 蓝牙驱动、Flash Memory Driver 内存驱动、Binder (pc)Driver 进程驱动、USB Driver、Audio Driver 音频驱动、Power Managemnet 电源管理、WIFI Driver 无线驱动、Keypad Driver 键盘驱动。


0x2 Android 真实架构

事实上,上面所述并不能真实反映Android的核心模块,其架构图在一开始就因为作者的私心被简化了,少了一些关键部分。下图出自 Android 源码官网,其中文网站仍然没有作更改

实际上 科学上网 浏览谷歌源码官网,你会发现架构图已经有所变化,能够大致表现各个层的位置关系了。所以真实的架构图应该是下面这样的1

这里可以看到,Android 的架构还有 Bionic、JNI。应用可以直接运行在 Dalvik 虚拟机中,也可以经过框架层间接运行在虚拟机上。如果涉及到一些底层操作,应用可以利用Java的特性,即JNI,调用C/C++ 原生库函数,提高了系统的效率。一些原生二进制也可以依赖这些库函数,直接运行。上层与内核直接有一个明确的分界线,即 Bionic,这是 Android 一次巨大的飞跃,也是其与 Linux 发行版不一样的地方之一。 这也是 Android 的魅力所在。


0x3 Android 与 Linux 的异同

Android 内核源码树在Linux 2.6.27版本中,从Linux内核主线分离,到了 Android 3.3 又回归 Linux 内核主线。谷歌主要维护各种框架(framework)以及 AOSP(安卓开源项目)。在内核态,Android 与 Linux 有 95% 相似1

在用户态,Android 引入了两个全新的组件,即 Dalvik 虚拟机和 HAL,再加上使用 Bionic 替换了 Linux 中的 glibc,以及定制了一个初始化守护进程 init,Android 与 Linux 显得相当不一致。
在这里插入图片描述
The Android Architecture, compared with that of mainstream Linux 2

Bionic

这张图清晰的表明了 Android 与 Linux 的差异。Android 替换了 Linux 发行版中的一个著名核心库——libc.so,使用了自己的C运行时库,也就是我们所说的 Bionic。谷歌公司给自己留了后手,使用 BSD 许可 Bionic,BSD 许可证有限开源。因为谷歌如果使用 glibc 库,因为 libc 本身使用 GPL 开源协议,根据 GNU 规则,Android 也必须开源。 当然,从技术层面上来书,Android 也有不使用 libc 的理由

Bionic库仅为200KB大小是GNU版本体积的一半,这意味着更高的效率和低内存占用,同时配合经过优化的Java VM Dalvik才可以保证高的性能。Bionic不支持一些特性比如宽字节对unicode,类似c++那样的异常处理。

  • 精简对系统调用的支持
  • 不支持 System V IPC
  • 有限的 Pthread 功能
  • 有限支持C++

JNI

由于 Android 应用是运行在虚拟机里的,开发者通常使用 Java/Kotlin 等高级语言编写应用,但是有时候避免不了访问硬件等功能,也就是说还需要执行虚拟机以外的代码。Dalvik 虚拟机就允许通过 Java 语言的 JNI(Java Native Interface)使用原生代码,即 ELF。而Linux发行版就不存在这个问题,也不存在这种调用关系。

Dalvik

Dalvik 这个名称相信大家都不陌生,来源于作者出生的一个北欧(冰岛)的小渔村的名字。Android 对 Linux 最大的扩展之一就是引入了 Dalvik 虚拟机。虽然和 Java 虚拟机一样,都可以运行 Java 代码,但是,Dalvik 虚拟机是一种基于寄存器的虚拟机,运行的是DEX字节码文件,而且针对移动平台做了专门的优化,这是与 Java 虚拟机有着天壤之别。

框架

Android 取得的巨大成功离不开它提供的框架,正式因为这些框架,开发者可以很便捷的使用高级语言开发应用,而不像 Linux 发行版,使用 C/C++ 进行原生开发。这对开发者来说,无疑是巨大的进步,重复造轮子的时代一去不复返。大量可供开发者调用的 API,能够大大缩短开发时间,软件生命周期的迭代时间也缩短不少,这也是为什么 Android 能够在移动互联网时代大放光彩的关键原因之一。


0x4 总结

Android 技术日新月异,几乎每年都会有重大更新,时至今日,Android 10 已经腾空出世,网上关于 Android 的文章也是汗牛充栋,笔者在这里仅仅作此小结,突出与其他介绍架构的文章不一样的地方,希望大家读后都能够有所认识。


  1. http://newandroidbook.com/AIvI-M-RL1.pdf ↩︎ ↩︎

  2. http://newandroidbook.com/ ↩︎

这篇关于另一角度看Android:Android 系统架构与 Linux 对比分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/634341

相关文章

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py

CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比

《CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比》CSS中的position属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布... css 中的 position 属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布局和层叠关

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

Linux系统中的firewall-offline-cmd详解(收藏版)

《Linux系统中的firewall-offline-cmd详解(收藏版)》firewall-offline-cmd是firewalld的一个命令行工具,专门设计用于在没有运行firewalld服务的... 目录主要用途基本语法选项1. 状态管理2. 区域管理3. 服务管理4. 端口管理5. ICMP 阻断