Android 系统启动过程概述

文章摘抄自 Android系统开发进阶-系统启动流程概要,稍作修改。

(图片来自:gityuan.com/android/)

Android 系统启动过程由上图从下往上的一个过程是由 Boot Loader 引导开机,然后依次进入 -> Kernel -> Native -> Framework -> App

BootLoader

板子上电后,芯片从固化在 ROM 里预设的代码(BOOT ROM)开始执行, BOOT ROM 会加载 Bootloader 到 RAM,然后把控制权交给 BootLoader。BootLoader 的作用是初始化硬件设备,加载内核文件,然后启动内核

Linux Kernel

Linux 内核负责初始化各种软硬件环境,加载驱动程序,挂载根文件系统(/)等,最重要的是,内核启动完成后,它会在根文件系统中寻找 "init" 文件,然后启动 init 进程。

init 进程

init 进程是 Linux 系统中用户空间的第一个进程,进程号为 1,我们可以说它是 root 进程或者所有进程的父进程。源码路径为: Android/system/core/init/

init 进程的主要工作如下:

  • 挂载虚拟文件系统:如 /sys、/dev、/proc
  • 启动 property 服务
  • 启动 SELinux
  • 解析执行 init.rc 文件

zygote 进程

上面提到 init 进程在解析 init.rc 时,会创建 zygote 进程,它是 Android 系统最重要的进程之一。后续 Android 中的 App 进程都是由 zygote 进程 fork 出来的。因此,zygote 是 Android 系统所有应用的父进程。zygote 进程的实际执行文件并不是 zygote,而是 /system/bin/app_process。源码路径为: Android/frameworks/base/cmds/app_process/。 它会调用 frameworks/base/core/jni/AndroidRuntime.cpp 提供的接口启动 java 层的代码 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java。至此,我们就进入到了 java 的世界。

zygote 的主要工作如下:

  • 创建 java 虚拟机 AndroidRuntime
  • 通过 AndroidRuntime 启动 ZygoteInit 进入 java 环境。

ZygoteInit 的主要工作如下:

  • 创建 socket 服务,接受 ActivityManagerService 的应用启动请求。
  • 加载 Android framework 中的 class、res(drawable、xml信息、strings)到内存。Android 通过在 zygote 创建的时候加载资源,生成信息链接,再有应用启动,fork 子进程和父进程共享信息,不需要重新加载,同时也共享 VM。
  • 启动 SystemServer。
  • 监听 socket,当有启动应用请求到达,fork 生成 App 应用进程。

zygote 进程的出现是为了能更快的启动应用。因为在 Android 中,每个应用都有对应一个虚拟机实例(AndroidRuntime)为应用分配不同的内存地址。如果 Android 系统为每一个应用启动不同的虚拟机实例,就会消耗大量的内存以及时间。因此,更好的办法应当是通过创建一个虚拟机进程,由该 VM 进程预加载以及初始化核心库类,然后,由该 VM 进程 Fork 出其他虚拟机进程,这样就能达到代码共享、低内存占用以及最小的启动时间,而这个 VM 进程就是 zygote。

SystemServer 进程

与 Zygote 进程一样,SystemServer 进程同样是 Android 系统中最重要的进程之一。它的源码路径为: Android/frameworks/base/services/java/com/android/server/SystemServer.java

SystemServer 的主要的作用是启动各种系统服务,比如 ActivityManagerService,PackageManagerService,WindowManagerService 以及硬件相关的 Service 等服务,我们平时熟知的各种系统服务其实都是在 SystemServer 进程中启动的,这些服务都运行在同一进程(即 SystemServer 进程)的不同线程中,而当我们的应用需要使用各种系统服务的时候其实也是通过与 SystemServer 进程通讯获取各种服务对象的句柄进而执行相应的操作的。在所有的服务启动完成后,会调用各服务的 service.systemReady(...) 来通知各对应的服务,系统已经就绪。

Launcher 的启动

Launcher 的启动比较复杂,而且不同版本的 Android 系统启动逻辑可能也不太一样,所以这里就不具体讨论,后续再专门讨论。但我们可以大概说明一下启动的策略。

我们知道 SystemServer 进程再启动的过程中会启动PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。SystemServer启动完所有的服务后,会调用各服务的 service.systemReady(...)。Launcher 的启动逻辑就在 ActivityManagerService.systemReady() 中。

BootAnimation 退出

Launcher 启动完之后,我们还看不到 Launcher,因为被 BootAnimation 的画面挡住了。BootAnimation 的退出也比较复杂,后续再详细讨论。大概是第一个应用起来之后,其 ActivityThread 线程进入空闲状态时,会通过某种机制把 BootAnimation 给退出。这里的第一个应用自然就是 Launcher了。这样就能确保在 BootAnimation 退出后,用户看到的不是黑屏,而是我们的桌面了。

总结

至此,Android系统总算是启动完成了,上面提到的这些步骤都是非常复杂的,每个步骤都可以单独花一篇或者几篇来讨论。现在我们只需要有一个整体的概念就行,其他的细节问题后续再慢慢研究。

参考资料

相关推荐
雨白5 小时前
Android 快捷方式实战指南:静态、动态与固定快捷方式详解
android
hqk5 小时前
鸿蒙项目实战:手把手带你实现 WanAndroid 布局与交互
android·前端·harmonyos
LING5 小时前
RN容器启动优化实践
android·react native
恋猫de小郭8 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker13 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴13 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭1 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab1 天前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe1 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农2 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos