Android 系统启动与运行机制全景解析

第一章:Android 系统启动流程

1.1 启动阶段概述

Android 系统从按下电源键到 Launcher 显示,共经历六个阶段:

  • Bootloader
  • Linux Kernel 初始化
  • Init 进程启动
  • init.rc 解析与守护进程启动
  • Zygote 与 SystemServer 启动
  • Launcher 启动

【补充】此六阶段模型是理解 Android 系统架构的基础。

1.2 Bootloader 阶段

当设备通电后,CPU 会从芯片中固化的一个地址开始执行代码,这个地址通常指向 Boot ROM。Boot ROM 中的代码会加载 Bootloader 到 RAM 中,并跳转执行。Bootloader 负责初始化硬件(如时钟、内存控制器等),然后加载 Linux 内核镜像(通常是 boot.img)到内存,并跳转到内核入口开始执行。

1.3 Linux 内核初始化阶段

Linux 内核启动后,首先会创建两个特殊的进程:

  • swapper 进程(pid=0):也称 idle 进程,是内核的空闲进程;
  • kthreadd 进程(pid=2):内核线程管理器,负责创建和管理其他内核线程。

内核完成中断、调度器、内存管理等子系统的初始化后,会加载必要的驱动模块(如显示、存储、输入设备驱动),挂载 tmpfs、proc、sysfs 等虚拟文件系统,最后执行用户空间的第一个程序:/init。

1.4 Init 进程启动(PID=1)

init 是用户空间的第一个进程(PID=1),也是所有用户进程的祖先。它主要完成以下工作:

  • 挂载 /system、/vendor、/data 等系统分区;
  • 创建 /dev、/mnt、/acct 等关键目录;
  • 启用 SELinux 安全策略;
  • 启动属性服务(Property Service),该服务提供全局配置的读写接口,例如 ro.build.version 等系统属性。

【补充】SELinux 在此阶段激活,后续所有进程的行为都将受到其安全策略约束。

📚 更多关于 init 进程的深度解析,可参考:init进程

1.5 解析 init.rc 并启动系统守护进程

init 进程会读取 /init.rc 文件以及它所 include 的其他 .rc 文件(例如 zygote.rc),按照其中的声明顺序启动一系列关键的系统服务,包括:

  • servicemanager:Binder 驱动的服务注册中心,所有 Binder 服务都必须向它注册;
  • hwservicemanager:用于 Treble 架构,管理 HIDL HAL 服务的注册;
  • adbd:Android Debug Bridge 守护进程,提供调试接口;
  • logd:日志系统后台服务;
  • zygote:Java 应用进程的孵化器,这是 Android 系统中最重要的进程之一。

【重要说明】这些服务并非由 init 主动创建,而是通过 init.rc 脚本中的 service 块被动触发,init 通过 fork + exec 方式启动它们。

系统架构图
启动流程图

📚 关于 init 进程如何管理子进程生命周期,详见:init进程

1.6 Zygote 与 SystemServer 启动

Zygote 进程在启动时会预加载 Android Framework 中常用的 Java 类(如 Activity、View、Intent 等)以及公共资源(如 R 文件)。这样,当需要启动一个新的应用进程时,只需通过 fork() 系统调用复制 Zygote 的进程镜像,即可直接复用这些已加载的类和资源,从而大幅缩短应用启动时间。

SystemServer 进程是由 Zygote 通过 fork() 创建的,它会执行 com.android.server.SystemServer 类的 main 方法。SystemServer 负责启动 Android 系统中超过 90 个核心服务,这些服务被分为三类依次启动:

  1. 引导服务(Bootstrap Services):包括 ActivityManagerService (AMS)、PackageManagerService (PMS)、WindowManagerService (WMS) 等;
  2. 核心服务(Core Services):包括 BatteryService、UsageStatsService、WebViewUpdateService 等;
  3. 其他服务(Other Services):包括 BluetoothService、WifiService、UsbService 等。

【补充】Zygote 与 AMS 之间的通信使用的是 LocalSocket,而不是 Binder。这是因为 AMS 向 Zygote 发送的 fork 请求数据量非常小(只包含包名、uid、gids 等),使用 Socket 的开销更低,且无需经过 Binder 的权限校验流程。

📚 Zygote 的双进程模型(zygote64 / zygote_secondary)详解:zygote进程

1.7 Launcher 启动

当 SystemServer 成功启动并完成所有核心服务的初始化后,ActivityManagerService (AMS) 会发送一个 Intent,其 action 为 ACTION_MAIN,category 为 CATEGORY_HOME。这个 Intent 会被 Launcher 应用接收。Zygote 接收到 AMS 的请求后,会 fork 出一个新的进程来运行 Launcher。至此,系统完成了从硬件上电到用户可见界面的全过程。

【补充】此后,所有普通应用的进程都是通过同样的方式——由 Zygote fork 生成。


第二章:PackageManagerService (PMS) —— APK 扫描与解析机制

2.1 PMS 的初始化时机与职责

PackageManagerService(简称 PMS)是在 SystemServer 启动过程中,作为引导服务(Bootstrap Services) 之一被创建的。它的核心职责是:

  • 扫描设备上所有预置和用户安装的 APK 文件;
  • 解析每个 APK 的 AndroidManifest.xml;
  • 提取并注册四大组件(Activity、Service、BroadcastReceiver、ContentProvider)信息;
  • 为系统其他模块(如 AMS)提供组件查询与权限校验能力。

2.2 APK 扫描路径与优先级

PMS 会按以下顺序和优先级扫描多个目录中的 APK:

  1. /system/framework
    存放系统核心库(如 android.jar、framework-res.apk),具有最高优先级。

  2. /system/app
    系统内置应用(如 Settings、SystemUI),优先级次之。

  3. /vendor/app
    厂商定制应用。

  4. /data/app
    用户通过应用商店或 adb 安装的应用,优先级最低。

【补充】扫描顺序决定了同名包的覆盖规则:高优先级目录中的 APK 会覆盖低优先级目录中的同名包。

2.3 扫描与解析过程细节

PMS 对每个 APK 执行以下操作:

  • 使用 PackageParser 读取 APK 文件;
  • 解压并解析 AndroidManifest.xml
  • 提取 package name、version、permissions、uses-sdk 等元数据;
  • 遍历四大组件声明,为每个组件创建对应的对象(如 ActivityInfo、ServiceInfo);
  • 将所有信息封装到一个 PackageParser.Package 对象中,并存入内部集合。

【关键细节】每个 APK 对应一个 Package 对象,其内部的组件(如 Activity)以 ArrayList<ActivityInfo> 形式存储。

2.4 异常处理机制

PMS 在扫描过程中会对不同类型的 APK 采取不同的容错策略:

  • 系统 APK(/system/app 等):即使解析失败,也不会删除文件,但会记录严重错误日志;
  • 非系统 APK(/data/app):若解析失败(如 Manifest 格式错误、签名无效),PMS 会直接删除该 APK 文件,防止无效应用残留。

【补充】这一设计确保了系统启动后,所有已知组件都是合法且可调度的。


第三章:WindowManager 体系架构与窗口管理机制

3.1 WindowManager 的三层抽象模型

Android 的窗口管理系统采用清晰的三层架构,将应用层、客户端与系统服务解耦:

  1. Window(应用层)

    • 是一个抽象类,代表一个窗口容器;
    • 在 Activity 中的实际实现类为 PhoneWindow
    • 负责持有 DecorView(根视图)并管理窗口属性(如标题栏、背景等)。
  2. WindowManager(客户端接口)

    • 是一个接口,提供给应用程序使用的窗口操作 API;
    • 实现类为 WindowManagerImpl
    • 应用通过它调用 addView()updateViewLayout()removeView() 等方法。
  3. WindowManagerService(WMS,系统服务)

    • 运行在 SystemServer 进程中;
    • 是窗口管理的真实执行者;
    • 负责窗口的创建、布局计算、Z-order 排序、动画驱动、Surface 分配及与 SurfaceFlinger 的交互。

【补充】这种分层设计使得应用无需关心底层图形合成细节,同时保证系统对窗口的统一管控。

📚 完整窗口机制解析:Android Window 机制

3.2 WMS 中的关键对象

WindowState

  • 每个窗口在 WMS 内部都有一个对应的 WindowState 对象;
  • 它记录了窗口的尺寸、位置、类型(TYPE_APPLICATION / TYPE_STATUS_BAR)、可见性、Token 引用等状态信息;
  • 是 WMS 进行布局计算和绘制调度的基本单位。

WindowToken

  • WindowToken 是一组窗口的逻辑容器;
  • 例如,一个 Activity 的所有窗口(Activity Window + Dialogs + PopupWindows)共享同一个 WindowToken;
  • Token 由 AMS 在启动 Activity 时创建,并传递给 WMS;
  • WMS 通过 Token 确保同一任务内的窗口具有相同的生命周期和层级归属。
Window和WindowState关系
Window和WindowToken关系

3.3 添加 View 的完整流程

当应用调用 WindowManager.addView(decorView, params) 时,系统执行以下步骤:

  1. 创建 ViewRootImpl

    • WindowManagerImpl 会为该 View 创建一个 ViewRootImpl 实例;
    • ViewRootImpl 是 View 树与 WMS 之间的桥梁。
  2. 绑定 DecorView

    • 将传入的 DecorView 与 ViewRootImpl 绑定;
    • 设置 LayoutParams。
  3. 触发首次绘制流程

    • 调用 requestLayout(),触发 measure → layout → draw
    • 但此时尚未真正显示,因为未与 WMS 建立连接。
  4. 通过 Binder 调用 WMS 的 addWindow()

    • ViewRootImpl 通过 Binder IPC 调用 WMS 的 addWindow() 方法;
    • 传入参数包括:View 的 LayoutParams、InputChannel、Display ID 等。
  5. WMS 分配 Surface 并注册到 SurfaceFlinger

    • WMS 验证权限和 Token 合法性;
    • 创建 WindowStateWindowSurfaceController
    • 向 SurfaceFlinger 申请一个 Surface
    • 将 Surface 的生产端(Producer)通过 Binder 返回给 App 进程。
  6. App 端开始绘制

    • App 拿到 Surface 后,通过 CanvasOpenGL 向其写入图形数据;
    • SurfaceFlinger 在 VSync 信号到来时合成所有 Surface 并输出到屏幕。
WMS职责
过程

【补充】整个过程依赖 Choreographer 监听 VSync 信号,在 doFrame() 回调中驱动绘制流水线,确保画面流畅。

3.4 Surface 的管理机制

  • WMS 创建真实 Surface:App 进程中的 Surface 对象只是一个空壳,真正的图形缓冲区由 WMS 通过 SurfaceFlinger 创建;
  • App 仅持有引用:App 通过 Binder 获取 Surface 的“生产端”(IGraphicBufferProducer),用于提交帧数据;
  • 线程安全:Surface 的写入操作需在 UI 线程或 GL 线程进行,避免并发冲突。

3.5 输入事件通道

  • 每个窗口在添加时,WMS 会为其创建一对 InputChannel(基于 Socket FD);
  • 一端留在 WMS,用于接收 InputDispatcher 的事件;
  • 另一端通过 Binder 传回 App 进程,由 ViewRootImplInputEventReceiver 监听;
  • 事件在 App 主线程中分发给对应 View。
输入事件通讯模型

📚 深入 WMS 实现:无处不在的WMSWindowManager体系


第四章:Activity 生命周期

4.1 Activity 启动初始化流程

当 AMS 决定启动一个 Activity 时,会通过 Binder IPC 通知目标应用进程的 ActivityThreadActivityThread 执行以下关键步骤:

▶ attach()

  • 创建 PhoneWindow 对象;
  • 将当前 Activity 设置为 PhoneWindow 的 Callback;
  • 调用 window.setWindowManager(),将 Activity 与 WindowManager 关联;
  • 此时 Window 已创建,但尚未添加到 WMS,因此没有有效的 WindowToken。

▶ setContentView()

  • 调用 PhoneWindow.setContentView()
  • inflate 用户指定的布局文件;
  • 创建 DecorView(整个 View 树的根容器);
  • 将用户布局添加到 DecorView 的 content 区域(ID 为 android.R.id.content);
  • 此时 View 树已构建完成,但仍未调用 WindowManager.addView(),因此不会触发 measure/layout/draw,也不会显示在屏幕上。

【关键说明】只有在 Activity 的生命周期推进到 onResume() 阶段后,AMS 才会通知 WMS 添加窗口。


4.2 完整生命周期方法详解

以下为原文中对每个生命周期方法的完整描述,未做任何删减

onCreate(Bundle savedInstanceState)

  • 开发者在此方法中进行初始化操作,如调用 setContentView()、findViewById、绑定数据等;
  • 系统会传入 savedInstanceState 参数,用于恢复因异常销毁前的状态;
  • 此时 Activity 的 Window 尚未注册到 WMS,WindowToken 为 null
  • 不能在此弹出 Dialog 或 PopupWindow,否则会抛出 “Unable to add window – token null is not valid” 异常。

onStart()

  • Activity 对用户可见,但尚未获得焦点;
  • WMS 已接收到 AMS 的请求,开始为该 Activity 分配 WindowToken;
  • Surface 尚未创建,View 树不可交互;
  • 可在此执行轻量级的可见性相关逻辑(如启动动画预加载)。

onResume()

  • Activity 进入前台,获得焦点,可与用户交互;
  • Input 事件通道已建立,触摸、按键事件可正常分发;
  • 注意:尽管此时 Activity 已“resume”,但在某些机型或系统版本上,首次在 onResume() 中立即弹出 PopupWindow 仍可能失败,原因在于 WMS 的 Token 注册与 Surface 分配存在微小延迟;
  • 推荐做法:将弹窗操作延迟到 onWindowFocusChanged(true) 回调中,或通过 View.post() 发送到消息队列尾部执行。

onNewIntent(Intent intent)

  • 触发条件:当 Activity 的启动模式为 singleTopsingleTask,且该 Activity 实例已存在时,再次启动它不会创建新实例,而是复用现有实例,并调用 onNewIntent()
  • 作用:用于接收新的 Intent 数据;
  • 注意事项
    • onNewIntent() 中,应调用 setIntent(intent) 更新当前 Activity 的 Intent,否则后续调用 getIntent() 仍返回旧的 Intent;
    • 此方法可能在任意生命周期状态后被调用(如 Activity 在后台时被启动),因此不应假设 UI 已可见或已 resume;
    • 常见使用场景:推送通知点击、Deep Link 跳转、跨应用数据传递。

【示例】

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent); // 必须调用,否则 getIntent() 返回旧值
    handleNewIntent(intent);
}

onPause()

  • Activity 失去焦点(例如:启动新 Activity、弹出 Dialog、来电界面覆盖);
  • 必须快速返回,不能执行耗时操作,否则会导致 ANR(Application Not Responding);
  • 系统可能在此之后杀死进程,因此不应依赖此方法保存持久化数据
  • 通常用于暂停动画、释放传感器、注销广播接收器等轻量级清理。

onStop()

  • Activity 完全不可见(被其他 Activity 完全覆盖或进入后台);
  • 可在此释放重量级资源,如停止网络请求、关闭数据库连接、注销位置监听;
  • 若因配置变更(如屏幕旋转)导致重建,系统会在 onStop() 之后调用 onDestroy()

onDestroy()

  • Activity 被销毁;
  • 所有资源应在此彻底释放;
  • 若由 finish() 触发,则 isFinishing() 返回 true;
  • 若因系统内存不足被回收,则此方法可能不会被调用。

4.3 onSaveInstanceState() 的调用时机(版本差异)

原文明确指出以下版本行为差异,完整保留

  • 在 Android API 级别 28(Android 9.0)之前
    onSaveInstanceState()onPause() 之后、onStop() 之前调用。

  • 从 Android API 级别 28(Android 9.0)开始
    onSaveInstanceState() 被移至 onStop() 之后调用。

【原因说明】Google 作出此调整是为了避免开发者在 onStop() 中释放的资源(如 Bitmap、数据库连接)被 onSaveInstanceState() 误用,从而引发空指针或状态不一致问题。

【建议】不要在 onSaveInstanceState() 中访问可能已在 onStop() 中释放的对象。


4.4 AMS 与 Activity 的协作机制

  • AMS 作为系统服务,维护所有 Activity 的状态机;
  • 当需要切换 Activity 状态时,AMS 通过 Binder 向目标进程的 ApplicationThread 发送指令;
  • ActivityThreadH(Handler)接收到消息后,反射调用对应 Activity 的生命周期方法;
  • Activity 本身不具备主动控制权,其生命周期完全由 AMS 驱动;
  • 因此,Activity 是 AMS 管理的一个被动状态机,应用代码只是状态变更的响应者。

📚 完整生命周期详解:Activity生命周期

生命周期

📚 更多 AMS 与 WMS 协作细节:WMS/AMS 窗口层级结构解析


第五章:其他关键技术机制

5.1 Zygote 与 AMS 的通信机制

  • AMS 在需要启动新应用进程时,不会直接 fork 进程,而是通过 LocalSocket 向 Zygote 发送请求;
  • 请求内容包括:目标 APK 的包名、用户 ID(uid)、组 ID(gids)、调试标志等;
  • Zygote 接收到请求后,执行 fork() 创建子进程,并在子进程中调用 RuntimeInit.zygoteInit(),最终启动目标 ActivityThread;
  • 为何使用 Socket 而非 Binder?
    • 因为 fork 请求数据量极小(通常 < 1KB);
    • Socket 在小数据量下延迟更低、开销更小;
    • Binder 需要跨进程权限校验和上下文切换,不适用于高频、轻量的进程孵化场景。

📚 Zygote 的双进程模型(zygote64 / zygote_secondary)详解:zygote进程


5.2 Input 事件通道机制

  • 每个窗口在通过 WMS.addWindow() 注册时,WMS 会为其创建一对 InputChannel
  • InputChannel 基于 Unix Domain Socket 的文件描述符(FD) 实现;
  • 一端保留在 WMS,用于接收 InputDispatcher 分发的触摸、按键事件;
  • 另一端通过 Binder 传递给 App 进程,由 ViewRootImpl 中的 InputEventReceiver 监听;
  • 关键特性
    • 单线程读取:事件必须在主线程中处理,保证顺序性;
    • 线程安全:底层 FD 读写加锁,避免并发冲突;
    • 低延迟:直接通过内核 socket 传递,绕过 binder transaction 开销。
输入事件通讯模型

5.3 Choreographer 与动画驱动机制

  • Android 的 UI 绘制与动画依赖 VSync(垂直同步)信号
  • Choreographer 是系统提供的协调器,用于监听 VSync 信号;
  • 当应用调用 invalidate() 或启动动画时,会向 Choreographer 注册回调;
  • 在下一个 VSync 到来时,Choreographer 执行 doFrame() 方法,依次触发:
    1. Input 处理(分发触摸事件);
    2. Animation 更新(计算属性动画新值);
    3. Traversal(measure → layout → draw);
    4. Surface 提交(将帧数据提交给 SurfaceFlinger);
  • 此机制确保所有 UI 操作以 60fps(或设备刷新率) 同步执行,避免画面撕裂和卡顿。

【补充】若主线程阻塞导致 doFrame 无法及时完成,就会出现掉帧(jank)。


5.4 Surface 管理细节

  • App 端的 Surface 对象是空的:它只是一个壳,不包含真实的图形缓冲区;
  • 真实 Surface 由 WMS 创建:WMS 调用 SurfaceFlingercreateSurface() 方法申请一个 Layer
  • 生产者-消费者模型
    • App 进程持有 生产者端(IGraphicBufferProducer),用于填充像素数据;
    • SurfaceFlinger 持有 消费者端(IGraphicBufferConsumer),用于合成并输出;
  • 生命周期绑定窗口:当窗口被移除(如 Activity finish),WMS 会销毁对应的 Surface,释放 GPU 内存。

📚 深入 WMS 实现:无处不在的WMSWindowManager体系

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

友情链接更多精彩内容