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 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹6 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空8 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭8 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日9 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安9 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑10 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟14 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡15 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0015 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体