前言
在学习Android系统之前,我们必须要大体上对Android系统架构有个明确的认识,理解其中每一块的职责。
正文
这里我们从Android系统分层和源码目录这俩个方面来分析。
Android系统架构
关于Android系统架构,有如下一张非常经典的图可以表示:
这是一张静态图,只能描述Android系统架构的分层,一共5层,从上到下依次是应用层、应用框架层、系统运行库层、硬件抽象层和Linux内核层。
我们先简单介绍一下这几层的作用,然后再从进程角度从新来看。
应用层(System Apps)
系统内置的应用程序以及非系统级的应用程序都属于应用层,负责与用户进行交互,一般使用Java或者Kotlin开发,也就是我们所说的应用层开发。
应用框架层(Java API Framework)
这一层为应用层开发提供所需要的Java API,也就是我们常说的Android系统的Java源码,这一层由Java代码编写,所以叫做Java Framework。
从图中可以看出,这里主要有View System(视图系统,即基本组件)、内容提供器,和各种管理器,部分功能大致描述如下:
名称 | 功能描述 |
Activity Manager | 管理应用的生命周期,以及常用的导航回退功能 |
Location Manager | 提供地理位置和定位服务 |
Package Manager | 管理应用程序的安装 |
Notification Manager | 管理状态栏的通知 |
Resource Manager | 提供应用程序使用的各种非代码资源,比如本地字符串、图片、布局文件、颜色文件等 |
Window Manager | 管理应用程序的窗口 |
系统运行库层(Native)
从图中可以看出这里分为了俩个部分,分别是C/C++程序库和Android运行时库。
C/C++库
这些C/C++库程序可以被应用框架层所使用,至于为什么Android系统要使用C/C++库,而不都用Java库,原因主要是C/C++代码执行效率更高,而且很多功能有成熟的C++代码,不用重新写,主要C/C++程序库:
名称 | 功能描述 |
OpenGL ES | 3D绘图函数库 |
Libc | 标准C系统函数库,专门为嵌入式Linux的设备定制 |
Media Framework | 多媒体库 |
Webkit | WebView使用 |
OpenMAX AL | 一个多媒体应用程序的标准框架 |
SQLite | 轻量级的关系型数据库引擎 |
Android运行时库
这个部分非常容易被忽略,这里又分为了核心库和ART。其中核心库提供了Java语言核心库的大多数功能,这样开发者可以使用Java语言来编写Android应用。
而ART则是专门为移动设备定制的Java虚拟机,在之前还有被淘汰的Dalvik虚拟机,关于虚拟机的知识我们后面细说。这里要明白一点就是ART和JVM还是有很大的区别,它是由C++编写,用来运行Java程序,所以非常关键。而且Android系统还允许同时允许多个ART实例,这也就是我们常说的:在Android系统中,每个进程都有一个虚拟机,一个APP发生崩溃不会影响其他APP。
硬件抽象层(HAL)
硬件抽象层位于操作系统内核与硬件电路之间的接口层,目的就是将硬件抽象化,这样各种硬件就可以根据接口进行开发和适配。
Linux内核层(Linux Kernel)
Android的核心服务是基于Linux内核,同时在该基础上添加了Android专用的驱动,比如Binder。由于Linux系统的优秀性,基于Linux在安全性、内存管理、进程管理等都有了很大优势。
Android系统架构(进程角度)
前面所说的Android系统架构固然经典,但是却无法直观地看出系统的运行,因为代码是死的,而系统是活的。所以这里使用gityuan博客一张非常经典的图来让系统动起来:
这张图从进程的角度重新来审视Android系统架构,从上电开机到显示出APP页面的整个过程中涉及了哪些服务,创建了哪些进程,这样可以更让我们容易理解Android系统,下面简单说说每个流程。
Loader层
首先就是Boot ROM,当手机处于关机状态时,长按电源键开机,引导芯片从固化在ROM里的预设代码开始执行,然后机制引导程序到RAM中。
而Boot Loader就是引导程序,主要是检查RAM,初始化硬件参数等功能。
Linux内核层
前面我们知道Android系统是基于Linux内核,而这时会启动Linux内核的俩个主要进程:
- 启动Kernel的swapper进程(pid=0),该进程又称为是idle进程,是Kernel由无到有的第一个进程,用于初始化进程管理、内存管理,加载Display、Camera Driver、Binder Driver等工作。
- 启动kthreadd进程(pid=2),该进程是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd等内核守护进程。kthreadd进程是所有内核进程的鼻祖。
Native层
上面所说的都是Linux内核进程,而到Native层会创建init进程(pid=1),该进程是用户进程,也是所有用户进程的鼻祖。
init进程的主要作用:
- init进程会孵化出ueventd、logd、installd、adbd等用户守护进程(系统必需的一些服务)。
- init进程还会启动servicemanager(binder服务管家)、bootanim开机动画等重要服务。
- init进程还会孵化出用来管理C++ Framework库的Media Server进程。
- init进程会孵化出Zygote进程,Zygote进程是Android系统第一个Java进程(虚拟机进程),所以Zygote是所有Java进程的父进程。
而这里Native层和Linux内核层的通信是利用系统调用,关于系统调用简单来说就是Linux内核为了防止用户态的程序随意调用内核代码导致内核挂掉,所有想使用内核的服务都必须通过系统调用。
这里有一些同学之前认为C++层的代码就是内核层,其实不是的,真正内核层的只有Linux内核层,Native层是用户态的C/C++实现部分。
Java Framework层
Zygote进程是由init进程通过解析init.rc后fork而来,由Zygote进程开启Java世界,主要包括:
- 加载ZygoteInit类,注册Zygote Socket服务端套接字,这个是为了响应后面fork新进程的需求。
- 加载虚拟机,即创建ART虚拟机。
- 预加载类preloadClass。
- 预加载资源preloadResources。
然后Zygote进程还会孵化出System Server进程,该进程同时也是Zygote孵化的第一个进程,该进程非常熟悉了,它管理着Java framework,包括AMS、WMS等各种服务。
这里有个非常重要的点,就说JNI技术,通过JNI技术打通了Java世界和C/C++世界。
应用层
Zygote进程会孵化出第一个APP进程就是Launcher了,即桌面APP,每个APP至少运行在一个进程上,而这些进程都是由Zygote进程孵化而来。
经过上面的流程梳理,我们更可以发现Android系统设计的巧妙,每一层都有对应的作用,都由相应的进程来管理,我们可以通过Linux的ps命令来简单查看当前系统的所有进程。
Android系统源码目录
不想下载源码的,可以直接在该在线网址查看:aospxref.com/android-12.…
这里我们来看看Android系统源码的目录结构,有一个大致了解,在后面对找源码有帮助。整个目录如下,我这是android 12的源码:
Android源码跟目录 | 描述 |
art | ART运行环境 |
bionic | C库 |
bootable | 启动引导相关代码 |
build | 存放编译规则以及基础开发包配置 |
cts | 兼容性测试套件 |
dalvik | Dalvik虚拟机 |
developers | 开发者目录 |
development | 与应用程序开发相关 |
device | 设备相关配置 |
external | 开源模组相关文件 |
frameworks | 应用程序框架,Android系统核心部分,由Java和C++编写 |
hardware | 硬件抽象层代码 |
kernel | Linux内核代码和配置 |
libcore | 核心库 |
libnativehelper | 动态库,实现JNI库的基础 |
packages | 应用程序包 |
pdk | 本地开发套件 |
platform_testing | 平台测试 |
prebuilts | X86和ARM架构下预编译的一些资源 |
sdk | SDK和模拟器 |
system | 底层文件系统库 |
toolchain | 工具链文件 |
对上面几个常用的目录,再做一下说明:
packages目录 | 描述 |
apps | 系统应用程序目录 |
inputmethods | 输入法目录 |
modules | 一些模块组件程序 |
providers | 内容提供者目录 |
screensavers | 屏幕保护程序 |
services | 通信服务程序 |
wallpapers | 壁纸程序 |
然后就是应用框架部分,着部分是我们开发所涉及的核心部分,一方面给应用层开发提供API,另一方面与native库进行衔接,而主要目录就是在frameworks下的base和av目录:
frameworks/base目录 | 描述 |
core | 核心库 |
include | 头文件 |
libs | 库 |
media | 多媒体相关 |
opengl | 图形相关API |
cmds | am等命令 |
data | 字体和声音数据文件 |
native | 本地库 |
上面只是列出了一部分,还有很多知识,我们在使用到时再具体分析。
总结
本篇作为Android系统架构的概述,必须要清晰地理解Android系统的分层,以及每一层的作用。其次就是Android系统中涉及的重要进程,比如init、Zygote进程等,理解这些进程的运行,可以更好地从动态角度理解Android系统,在后面文章中,会对这些进程都仔细分析。