面试官:“请描述一下Android系统的启动流程”
作者:OpenGL
前言
什么是Android启动流程呢?其实指的就是我们Android系统从按下电源到显示界面的整个过程。
当我们把手机充好电,按下电源,手机会弹出相应启动界面,在等了一段时间之后,会弹出我们熟悉的主界面,这其实就是我们Android系统的整个启动过程。
本篇文章就是想跟大家聊一下我们的Android系统启动过程中到底经历了什么。
另外,本篇可以看成一篇介绍文章,会出现很多名词,这些词对于不了解底层的人来说可能会有些陌生, 在这里只会介绍他们的名称以及作用。一些重要的进程后续会出相应的文章。 而不需要了解的,可能在这里就一笔带过了。请各位谅解。
电脑是如何启动的呢
其实组装过电脑的人应该知道我们的电脑其实是由各式各样的硬件组成的。最重要的是CPU,他是用来进行计算的。 我们的鼠标键盘是用来输入的。显示器不管你是2K分辨率还是1080P分辨率都是用来显示图形界面的,另外还有音响等。
当然这里还有一个东西叫做主板,我们所有的硬件设备最终都要连接在主板上,无论是你通过线的形式,
 还是像CPU和内存一样直接被插在主板上。
当我们按下电源的启动键,会先执行主板上的启动程序,他会先执行一个叫做Bios的程序,如果你的电脑系统坏了,就要在Bios重新设置启动盘的加载路径,一般情况下是一个已经预装好系统的U盘,进而给我们的电脑重新安装系统。
Android的启动流程
1. 手机上的BIOS:BootLoader
上面讲了,电脑的启动流程。为啥要讲电脑的启动呢?因为Android的启动和它差不多。手机的所有硬件也都镶嵌在手机的主板上,只不过手机相对电脑的机箱来说,整体更加轻薄。
当我们手机关机进行启动的时候,我们第一件要做的就是按下电源键。按电源键,其实就是再给我们的手机主板通电。通电之后,我们的主板会启动一个BootLoader的程序,去已经设置好的位置加载我们的手机系统。这个BootLoader就相当于我们电脑的Bios。
在十年前,Android刚刚兴起的时候,相比于ios封闭的生态系统。Android系统的一些用户,非常喜欢做的一件事情就是刷机。
 而且各大厂商也会出相应的手机Rom包,给各个玩家刷机。现在的MIUI就是那时候兴起的,彼时的小米还没有做自己的第一部1999的手机,它做的只是Rom系统。
当然下场做系统的不止小米一家,还有百度的系统,阿里的系统,还有国外的CM团队做的系统。我记得当时高中的我有了一部三星的i9020俗称谷歌二太子,它本身是Android2.3系统的,后来Google推出了自己的Android4.0系统的Rom包给二太子,当时全世界第一批用上Android4.0的用户,就是拥有i9020手机的人。
那时候就是下载Rom包放到SDCard下,在进入BootLoader界面,双清所有设置,接着选择sdcard上的安装包,等待安装完毕再进行重启。就可以用上最新的Android4.0了。
所以说这个BootLoader就相当于电脑的Bios。
只不过现在的手机没有那么多的可玩性,不能换主板cpu,也没有相应的系统给用户进行刷机了。
2. Android的第一个进程:idle
Android是基于Linux系统内核做的一款移动端操作系统。所以在在BootLoader启动Android系统之后,它启动的第一个进程也和Linux一样,是idle进程。并且这个进程的 pid = 0。
基于Linux系统所以很多机制也和Linux比较相似,就比如说内核空间和用户空间。其实这属于一个比较抽象的概念。我们可以用后台系统类比一下方便理解。
假设你是一个后台管理人员。你的权限可能就是单纯的查看数据。但是新建账号或者删除数据这些功能你是无权使用的。你要是想使用这些功能的话需要获取更高的权限,也就是我们俗称的提权。
我们的操作系统在运行的时候,为了系统的稳定。会将整块内存区域分成两份,一份是系统运行的内存区域,要想操纵这块区域,或者运行某些函数往这块内存上修改数据,就必须拥有极高的权限,这块内存区域也就是内核空间。另一块区域就是运行一些普通的程序,这一块区域被称作用户空间。与之相对的,可以操作内核空间的权限被称作内核态,可以操作用户空间的权限被称作用户态
为什么会分成这两块呢,究其原因是为了安全稳定。如果,你是一个系统开发商,你的系统在运行的时候,客户随便点开一个App,这个App是一个恶意程序,它修改了你系统运行的某些内存数据,导致你的系统崩溃死机。久而久之,你的操作系统就会失去市场。所以Linux才会把内存分为用户空间和内核空间。
idle的主要作用
- 初始化进程以及内存管理,加载硬件的驱动程序
 - 创建init进程,该进程的pid=1,init进程是第一个用户空间的进程
 - 创建kthreadd进程,该进程pid=2,并且该进程仍属于内核空间
 - idle进程自己也运行在内核空间
 
2. 和内核相关的进程:kthreadd
对于kthreadd进程,我们其实并不需要知道太多,毕竟我们正常开发用不到关注内核相关的代码。我们只需要知道几点,
- kthread的进程pid=2
 - 内核相关的资源都是由这个进程创建而来的。
 - 该进程以及由它产生的子进程都运行在内核空间
 
3. 一切的开始:init进程
init进程,光听名字我们就知道他的重要性。这个进程也是由idle进程创建而来的,他的pid=1。并且它是第一个属于用户空间的进程。
init主要作用
- 该进程最主要的作用就是fork出了Zygote进程
 - 同时会创建ServiceManager进程。即我们俗称的服务大管家。
 
4. 最重要的进程:Zygote
Zygote英文翻译为受精卵,我们平时启动的所有进程等都是由这个进程复制而来。所谓复制就是,这个进程会复制出两份一模一样的进程,其中一个继续当Zygote进程,另一个进程执行完相关代码就变成了,你想启动的进程。但是在fork出别的进程之前,他要先进行一些初始化,这样fork出来的进程就和他一样自带这些初始化好的功能,而不是在初始化一遍。
Zygote的主要作用
- 创建虚拟机
 - 注册JNI
 - 启动ZygoteServer(实际就是Socket,用来跨进程通信)
 - preload 预加载资源,之后复制出的进程就都已经是加载过资源的进程了
 - 启动SystemServer
 - 循环等待,一旦AMS通知创建进程,就会进行进程分裂。
 
Zygote其他
这里多说一嘴,Zygote进程本身创建了JVM虚拟机,注册了JNI,也就是说我们的代码从这里开始,才真正的开始可以执行Java代码,之前运行的都是C++代码。
 另外,由于在fork进程之前进行了创建虚拟机注册JNI,以及预加载等工作。所以我们fork出的进程从出生开始,就自带了虚拟机,并且已经注册好了JNI代码,相应的资源也已经加载完毕了。
5.累死累活的工具人:SystemServer
为啥说它是累死累活的呢,因为几乎所有服务都是由SystemServer创建的。其中包括AMS,WMS,PMS等重要服务,都是运行在该进程上的,并且在该进程上注册到ServiceManager进程中。
6.柳暗花明有一村:Launcher
各位有没有想过,我们每天滑动手机时的界面到底是什么。其实它和我们开发的手机程序一样,都是一个App。只不过它是由Android系统自动启动的。并且,它可以把我们的所有安装的App全都显示出来,仅此而已。
 当我们点击Launcher上的App图标时,它会和AMS进行通信,AMS又和Zygote进行通信。Zygote进程fork出了一个新进程,并执行相关代码,从而我们编写的App就这样被创建了出来。
本章问题
- Android系统的启动流程都经历了什么
 - init进程都有哪些作用
 - zygote进程都干了什么
 - systemserver是由谁启动的呢
 - 我们平时看到的系统界面实际是什么
 
Android启动流程图解

Android 学习手册
Android Framework底层原理篇:https://qr18.cn/AQpN4J
 Android 性能优化篇:https://qr18.cn/FVlo89
 Android 车载篇:https://qr18.cn/F05ZCM
 Flutter 篇:https://qr18.cn/DIvKma
 Android 音视频篇:https://qr18.cn/Ei3VPD
 Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
 Kotlin 篇:https://qr18.cn/CdjtAF
 Gradle 篇:https://qr18.cn/DzrmMB
 OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
 Android 八大知识体:https://qr18.cn/CyxarU
 Android 核心笔记:https://qr21.cn/CaZQLo
 Android 面试题锦:https://qr18.cn/CKV8OZ
 Android 车载面试题:https://qr18.cn/FTlyCJ
相关文章:
面试官:“请描述一下Android系统的启动流程”
作者:OpenGL 前言 什么是Android启动流程呢?其实指的就是我们Android系统从按下电源到显示界面的整个过程。 当我们把手机充好电,按下电源,手机会弹出相应启动界面,在等了一段时间之后,会弹出我们熟悉的主…...
k8s delete node 后 重启kubelet会自己加入到集群 ?
原因 当执行kubectl delete node命令时,Kubernetes API服务器会收到该节点的删除请求,并将其从集群中删除。此时,kubelet服务在该节点上仍然在运行,但已经不再与集群通信。 当您重启kubelet服务时,它会重新向API服务…...
REXROTH液压方向阀安装须知
安装规程 阀安装到系统之前,应该对照订货型号比较其型号说明。 确认阀的连接表面和底板无水分,没有油。 - 清洁: ‧ 安装元件时,确认工业阀和周围干净 ‧ 油箱须密闭,以防止外部污染 ‧ 安装之前&…...
【数据结构实验】哈夫曼树
【数据结构实验】哈夫曼树 简介: 为一个信息收发站编写一个哈夫曼码的编/译码系统。文末贴出了源代码。 需求分析 完整的系统需要具备完整的功能,包含初始化、编码、译码、印代码文件和印哈夫曼树,因此需要进行相应的文件操作进行配合。哈…...
浏览器不好用?插件来帮忙
一、目的 浏览器本身具备的功能并不完善,不同的用户可以为自己浏览器增加想要功能,使得浏览器更能符合自己的需求,提高浏览器使用的舒适度 二、推荐插件 AdblockPlus LastPass(密码记录,全平台通用) Dar…...
Qt Quick - 容器控件综述
Qt Quick - 容器控件综述 一、概述二、ApplicationWindow Control三、Frame Control四、GroupBox Control五、Page Control六、Pane Control七、ScrollView Control八、StackView Control九、SwipeView Control十、TabBarControl十一、ToolBar控件 一、概述 Qt Quick Controls…...
面试题30天打卡-day06
1、什么是反射机制?说说反射机制的优缺点、应用场景? 反射机制:Java的反射机制是在运行状态,对于任意一个类,都能够动态的获得这个类的属性和方法;对于一个对象,都能动态的调用它当中的方法和属…...
Spring Boot的基础使用和< artifactId>spring-boot-maven-plugin</ artifactId>爆红的处理
Spring Boot的基础使用和< artifactId>spring-boot-maven-plugin</ artifactId>爆红的处理 Spring Boot概述 微服务概述 微服务Microservices是一种软件架构风格,他是以专注于单一责任与功能的小型功能区块Small Building Blocks 为基础,…...
项目管理中的必不可少的强大工具有哪些?
在项目管理中,我们总是想寻求一套功能强大的工具,来满足我们多样化的需求。但往往事与愿违,这样强大的工具总是费用高,操作复杂,需安装多个插件。下面,我就给大家推荐一款项目管理软件 ~Zoho Projects&…...
嵌入式学习笔记——SPI通信的应用
SPI通信的应用 前言屏幕分类1.3OLED概述驱动芯片框图原理图通信时序显示的方式页地址、列地址初始化指令 程序设计初始化代码初始化写数据与写命令清屏函数 初始化代码字符显示函数 总结 前言 上一篇中介绍了STM32的SPI通信,并根据框图和寄存器进行了SPI通信的初始…...
.Net下企业应用系统架构构建心得
在开始架构设计之前,需要了解一下架构是什么,按照IEEE标准的定义是: Architecture 是一个系统的基本组织,它蕴含于系统的组件中、组件之间的相互关系中、组件与环境的相互关系中、以及呈现于其设计和演进的原则中。 (The embodied…...
【社区图书馆】关于Mybatis原理学习的读后感
1、为什么会看原理书籍 Mybatis是我们Java后端开发中的主流ORM框架,基本都会在工作中用到。所以,是既熟悉,又陌生。熟悉是因为一直都在使用,而陌生则是对于其内部原理还不够深入。刚好近期的工作中,又遇到了一个需求&a…...
C++ Primer阅读笔记--表达式和运算符的使用
1--左值和右值 C 的表达式有右值(rvalue, are-value)和左值(lvalue, ell-value)两个形式;当一个对象被用作右值时,使用的是对象的值(内容);当对象被用作左值时࿰…...
npm install xxx的执行过程及示例
当你在终端中执行npm install xxx命令时,npm会执行以下步骤来安装软件包: 检查本地npm缓存中是否有该软件包。 如果本地npm缓存中已经存在该软件包,npm将直接从缓存中提取软件包并安装。这将显著加快安装速度,因为npm无需从网络下…...
excel数据分析比赛
基础 sql:百度网盘 请输入提取码 excel函数 <...
Git使用GitHub说明
GitHub为公网代码托管仓库,Git可以将本地仓库推送到GitHub管理。 步骤:1、注册GitHub账号 2、创建仓库(会得到一个仓库地址) 3、推送本地仓库 git remote add origin https://github.com/jianshengchuanqi/xuesezhanjiang.git…...
这些不可不知的JVM知识
JVM是面试中必问的部分,本文通过思维导图以面向面试的角度整理JVM中不可不知的知识。 先上图: JVM必备知识 1、JVM基本概念 1.1、JVM是什么 JVM 的全称是 「Java Virtual Machine」,也就是我们耳熟能详的 Java 虚拟机。 JVM具备着计算机的…...
基于RK3568的Linux驱动开发——GPIO知识点(一)
authordaisy.skye的博客_CSDN博客-Qt,嵌入式,Linux领域博主系列基于RK3568的Linux驱动开发—— GPIO知识点(二)_daisy.skye的博客-CSDN博客 gpio bank RK3568 有 5 组 GPIO bank:GPIO0~GPIO4,每组又以 A0-A7、B0-B7、 C0-C7、 D0…...
5.2.1二叉树的定义和基本术语
二叉树的基本概念: 二叉树是递归定义的二叉树 下面我们来看几个特殊的二叉树: 特点: 1)只有最后一层有叶子节点 2)不存在度为1的结点 3)按层序从1开始编号,结点i的左孩子为2i,右孩…...
动态组件、keep-alive的使用及自定义指令
目录 1. 动态组件 2.如何实现动态组件渲染 3. 使用keep-alive保持状态 4. keep-alive对应的生命周期函数 5. keep-alive的include属性 自定义指令 1.什么是自定义指令 2. 自定义指令的分类 3. 私有自定义指令 4. update函数 5. 函数简写 全局自定义指令: …...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
