不止是“开奶茶店”:从“三界”视角,重构 Android 启动架构

271 阅读4分钟

一句话总结:

Android 的启动,并非一条单向的时间线,而是一场**“创世三部曲”**:首先,Native 世界搭建起硬件与驱动的“盘古大陆”;然后,Zygote 作为“创世神”,架起通往新世界的“彩虹桥”;最后,Java Framework 世界在这片新大陆上拔地而起,构筑起繁华的应用生态。


第一幕:Native 世界的奠基——“盘古开天”

这是启动的最底层,完全由 C/C++ 代码主导,为整个系统打下硬件和底层软件的基础。

  1. Bootloader 引导:

    • 按下电源键,芯片自带的引导程序开始运行,它像一个“工头”,负责加载并启动 Android 的“地基”——Linux Kernel。
  2. Linux Kernel 启动:

    • 内核是连接软件与硬件的桥梁。它会初始化 CPU、内存等核心硬件,并加载必要的驱动程序。当内核准备就绪后,它会启动用户空间的第一个进程——init 进程。
  3. init 进程的“大爆炸”:

    • init 进程是所有用户空间进程的“始祖”。它会解析 init.rc 脚本,像执行一张“创世蓝图”一样,启动一系列至关重要的原生服务(daemon),其中最关键的有两个:

      • servicemanager: 整个 Binder IPC 体系的“通信基站”。它负责登记和查找系统中的所有 Binder 服务。
      • Zygote: 即将连接两个世界的“创世神”。

第二幕:Zygote 之桥——连接 Native 与 Java 的“彩虹桥”

Zygote(受精卵)是 Android 架构中最天才的设计。它是一个特殊的 Native 进程,其内部启动了 ART 虚拟机。它的使命只有一个:高效地孵化出所有的 Java 进程

Zygote 的两大“神力”:

  1. 预加载 (Preloading):

    • 在启动时,Zygote 会一次性地加载所有 Android App 都会用到的通用 Java 类(如 Activity, View)和系统资源。这就像提前准备好所有奶茶店都通用的“标准原料包”。
  2. 写时复制 (Copy-on-Write Fork):

    • 当需要启动一个新 App 时,Zygote 并不会重新创建一个完整的进程。它通过 fork 系统调用,近乎“零成本”地复制出一个子进程。
    • 魔法所在: 子进程在初期会与 Zygote 共享绝大部分内存。只有当子进程试图写入(修改)某块共享内存时,内核才会为它单独复制一份。这极大地加快了 App 的启动速度,并节省了大量内存。

第三幕:Java Framework 世界的诞生——“诸神就位”

有了 Zygote 这座桥梁,繁华的 Java 世界才得以构建。

  1. SystemServer 的诞生——“众神之王”:

    • Zygote 孵化的第一个、也是最重要的 Java 进程就是 SystemServer。它并非一个 App,而是整个 Android Framework 服务框架的宿主
    • SystemServer 在启动过程中,会实例化所有核心的系统服务,如 ActivityManagerService (AMS), WindowManagerService (WMS), PackageManagerService (PMS) 等。
    • 这些服务启动后,会立刻到 servicemanager(在 Native 世界)那里“注册”,宣告自己的存在。从此,Java 世界的服务就可以被其他进程通过 Binder 访问了。
  2. Launcher 的启动——“第一位凡人”:

    • SystemServer 的核心服务都准备就绪后,它会启动一个特殊的应用——Launcher(桌面)。
    • Launcher 的出现,标志着系统已准备就绪,可以与用户进行交互。
  3. App 进程的诞生——“万民繁衍”:

    • 当用户点击桌面上的图标时,Launcher 会通过 Binder 请求 AMS (在 SystemServer 中)。
    • AMS 随即通过一个 Socket 通道,向 Zygote 下达“孵化新进程”的指令。
    • Zygote fork 出一个新的 App 进程,这个进程继承了所有预加载的资源,并开始执行自己的应用代码。一个新 App 就此诞生。
graph TD
    subgraph "<b>第一幕: Native 世界 (C/C++)</b>"
        direction LR
        A[Bootloader] --> B[Linux Kernel];
        B --> C[Init 进程];
        C --> D(<b>servicemanager</b><br>Binder 总机);
        C --> E(<b>Zygote</b><br>创世神);
    end

    subgraph "<b>第二幕: Zygote 之桥</b>"
       E -- 启动 ART 虚拟机 --> F{预加载 Java 类库};
    end
    
    subgraph "<b>第三幕: Java Framework 世界</b>"
       direction LR
       F -- fork (CoW) --> G[<b>SystemServer</b><br>系统服务];
       G -- 启动 --> H(AMS, WMS, PMS...);
       H -- 注册到 --> D;
       G -- 启动 --> I[<b>Launcher App</b>];
       F -- fork (CoW) --> J[<b>普通 App 进程</b>];
       I -- 点击图标<br>请求 AMS --> J;
    end

结论:

Android 的启动流程,不仅仅是一系列枯燥的步骤,它深刻地体现了分层、解耦和空间换时间的架构哲学。从坚实的 Native 地基,到高效的 Zygote 桥梁,再到繁荣的 Java 上层生态,这套精巧的“创世”流程,是 Android 系统能够兼顾性能与灵活性的根本所在。