另一角度看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/ ↩︎

发布了24 篇原创文章 · 获赞 22 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/song_lee/article/details/104379673