2. Android系统架构概览

理解 Android 启动链,不能只盯着 init 进程本身,而要先建立一张“分层启动地图”。Android 系统自上而下通常划分为应用层、Framework 层、ART 运行时、Native 层、HAL 层和 Linux 内核层。它们并不是同时启动的,而是沿着“内核 → 用户空间 init → Native 服务 → HAL 服务 → ART/Framework → 应用”的顺序逐级被拉起。每一层都依赖下一层提供的进程、驱动、库或系统服务,形成一条清晰的依赖链。

核心结论:Android 启动不是“一次性把系统全部拉起来”,而是由 Linux 内核先建立运行环境,再由 init 按依赖关系分批启动 Native 服务、HAL、Framework 服务,最后才启动 Launcher 和普通应用。

一、六层架构与启动先后关系

从启动视角看,这六层可以这样理解:

  • Linux 内核层:最先运行,负责进程调度、内存管理、驱动加载、文件系统挂载,并启动第一个用户空间进程 init。
  • HAL 层:硬件抽象层,把摄像头、音频、传感器、蓝牙等硬件能力封装成统一接口,通常以 HAL 服务进程或直通库形式存在。
  • Native 层:C/C++ 实现的本地库与本地服务,如 servicemanager、surfaceflinger、logd、vold、netd 等,是 Framework 的底座。
  • ART 运行时:Android Runtime,负责执行 DEX 字节码,提供 GC、JIT、AOT 能力,是 Java/Kotlin 世界运行的前提。
  • Framework 层:Java 系统服务层,如 ActivityManagerService、PackageManagerService、WindowManagerService,通过 Binder 向应用提供 API。
  • 应用层:Launcher、SystemUI、设置、第三方 App 等,最后被启动并运行在 ART 之上。

下面这张图展示了各层在启动过程中的依赖方向与典型启动顺序:

Android 分层启动依赖关系 启动方向:内核 → init → Native/HAL → ART/Framework → 应用 ① ② ③ ④ ⑤ ⑥ Linux 内核层 进程调度 · 内存管理 · 驱动加载 · 文件系统 · 启动第一个用户空间进程 init HAL 层(硬件抽象层) Camera HAL · Audio HAL · Sensor HAL · Bluetooth HAL · 以 HAL 服务或直通库形式被 init 拉起 Native 层(C/C++ 本地服务与库) servicemanager · surfaceflinger · logd · vold · netd · Binder 驱动交互 ART 运行时 DEX 执行 · GC · JIT/AOT · 为 Java/Kotlin 系统服务与应用提供运行环境 Framework 层(Java 系统服务) ActivityManagerService · PackageManagerService · WindowManagerService · Binder 对外提供 API 应用层 Launcher · SystemUI · Settings · 第三方 App · 运行在 ART 与 Framework 之上 依赖 依赖 依赖 依赖 依赖

二、启动流程:init 如何按依赖拉起各层

Linux 内核完成初始化后,会执行 /system/bin/init,从此进入用户空间启动阶段。init 读取 init.rc 及其导入的 *.rc 文件,按照 on early-init、on init、on late-init、on boot 等触发器分阶段执行命令。典型顺序如下:

  1. 挂载文件系统、创建目录、设置权限,启动 ueventd 和 logd。
  2. 启动核心 Native 服务,如 servicemanager、vold、netd、surfaceflinger。
  3. 启动 HAL 服务,如 android.hardware.camera.provider、android.hardware.audio.service。
  4. 启动 zygote,由 zygote 预加载 ART 与常用类库,并 fork 出系统服务进程 system_server。
  5. system_server 启动 ActivityManagerService、PackageManagerService 等 Framework 服务。
  6. 系统服务就绪后,启动 Launcher 与 SystemUI,应用层开始呈现。

可以用一段简化的 rc 片段观察这种依赖关系:

on early-init
    start ueventd
    start logd

on init
    start servicemanager
    start vold
    start netd

on boot
    start surfaceflinger
    start zygote
    class_start hal
    class_start core

其中 servicemanager 必须先于大量 Binder 服务启动,否则其他服务无法注册;surfaceflinger 必须先于图形相关服务;zygote 必须先于 system_server。这就是“依赖决定顺序”的典型体现。

三、案例场景:从开机到桌面出现

以一台普通手机冷启动为例,可以观察到如下链路:

  • 内核启动约 1~2 秒,加载显示、触摸、存储等驱动。
  • init 启动 logd 后,内核日志开始转入用户空间日志系统。
  • servicemanager 就绪后,HAL 与 Native 服务才能通过 Binder 注册。
  • zygote 启动后,ART 完成预加载,system_server 被 fork 出来。
  • system_server 中的 PackageManagerService 扫描 APK,ActivityManagerService 准备启动 Launcher。
  • Launcher 进程启动,SurfaceFlinger 合成首帧,用户看到桌面。
排查开机问题时,可以按“内核 → init → Native → HAL → zygote → system_server → 应用”的顺序逐层确认。哪一层没有起来,问题通常就在该层或其下一层。

四、常见误区与复盘要点

很多初学者会把“系统架构分层”误认为“启动顺序也是从上到下”。实际上,应用层在最上面,却是最后启动的;Linux 内核在最下面,却是最先启动的。分层描述的是依赖关系,启动描述的是时间顺序,两者方向相反。

层级 典型对象 启动阶段 关键依赖
Linux 内核 调度、驱动、文件系统 最先 硬件与 bootloader
HAL Camera/Audio/Sensor HAL init 中期 内核驱动、Binder
Native servicemanager、surfaceflinger init 早中期 内核、HAL
ART zygote、DEX 运行时 init 后期 Native 库
Framework AMS、PMS、WMS zygote 之后 ART、Native 服务
应用层 Launcher、SystemUI 最后 Framework 服务
不要把 system_server 当成“第一个 Java 进程”。第一个 Java 进程是 zygote,system_server 是由 zygote fork 出来的系统服务进程。理解这一点,才能正确分析 ART 与 Framework 的启动边界。

复盘时可以抓住三条主线:第一,内核负责“能跑起来”;第二,init 负责“按依赖拉起服务”;第三,zygote 与 system_server 负责“把 Java 世界和系统服务准备好”。把这三条主线串起来,Android 六层架构的启动关系就清晰了。