作者:OpenGL
什么是Android启动流程呢?其实指的就是我们Android系统从按下电源到显示界面的整个过程。
当我们把手机充好电,按下电源,手机会弹出相应启动界面,在等了一段时间之后,会弹出我们熟悉的主界面,这其实就是我们Android系统的整个启动过程。
本篇文章就是想跟大家聊一下我们的Android系统启动过程中到底经历了什么。
另外,本篇可以看成一篇介绍文章,会出现很多名词,这些词对于不了解底层的人来说可能会有些陌生, 在这里只会介绍他们的名称以及作用。一些重要的进程后续会出相应的文章。 而不需要了解的,可能在这里就一笔带过了。请各位谅解。
其实组装过电脑的人应该知道我们的电脑其实是由各式各样的硬件组成的。最重要的是CPU,他是用来进行计算的。 我们的鼠标键盘是用来输入的。显示器不管你是2K分辨率还是1080P分辨率都是用来显示图形界面的,另外还有音响等。
当然这里还有一个东西叫做主板,我们所有的硬件设备最终都要连接在主板上,无论是你通过线的形式,
还是像CPU和内存一样直接被插在主板上。
当我们按下电源的启动键,会先执行主板上的启动程序,他会先执行一个叫做Bios的程序,如果你的电脑系统坏了,就要在Bios重新设置启动盘的加载路径,一般情况下是一个已经预装好系统的U盘,进而给我们的电脑重新安装系统。
上面讲了,电脑的启动流程。为啥要讲电脑的启动呢?因为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,也没有相应的系统给用户进行刷机了。
Android是基于Linux系统内核做的一款移动端操作系统。所以在在BootLoader启动Android系统之后,它启动的第一个进程也和Linux一样,是idle进程。并且这个进程的 pid = 0。
基于Linux系统所以很多机制也和Linux比较相似,就比如说内核空间和用户空间。其实这属于一个比较抽象的概念。我们可以用后台系统类比一下方便理解。
假设你是一个后台管理人员。你的权限可能就是单纯的查看数据。但是新建账号或者删除数据这些功能你是无权使用的。你要是想使用这些功能的话需要获取更高的权限,也就是我们俗称的提权。
我们的操作系统在运行的时候,为了系统的稳定。会将整块内存区域分成两份,一份是系统运行的内存区域,要想操纵这块区域,或者运行某些函数往这块内存上修改数据,就必须拥有极高的权限,这块内存区域也就是内核空间。另一块区域就是运行一些普通的程序,这一块区域被称作用户空间。与之相对的,可以操作内核空间的权限被称作内核态,可以操作用户空间的权限被称作用户态
为什么会分成这两块呢,究其原因是为了安全稳定。如果,你是一个系统开发商,你的系统在运行的时候,客户随便点开一个App,这个App是一个恶意程序,它修改了你系统运行的某些内存数据,导致你的系统崩溃死机。久而久之,你的操作系统就会失去市场。所以Linux才会把内存分为用户空间和内核空间。
对于kthreadd进程,我们其实并不需要知道太多,毕竟我们正常开发用不到关注内核相关的代码。我们只需要知道几点,
init进程,光听名字我们就知道他的重要性。这个进程也是由idle进程创建而来的,他的pid=1。并且它是第一个属于用户空间的进程。
Zygote英文翻译为受精卵,我们平时启动的所有进程等都是由这个进程复制而来。所谓复制就是,这个进程会复制出两份一模一样的进程,其中一个继续当Zygote进程,另一个进程执行完相关代码就变成了,你想启动的进程。但是在fork出别的进程之前,他要先进行一些初始化,这样fork出来的进程就和他一样自带这些初始化好的功能,而不是在初始化一遍。
这里多说一嘴,Zygote进程本身创建了JVM虚拟机,注册了JNI,也就是说我们的代码从这里开始,才真正的开始可以执行Java代码,之前运行的都是C++代码。
另外,由于在fork进程之前进行了创建虚拟机注册JNI,以及预加载等工作。所以我们fork出的进程从出生开始,就自带了虚拟机,并且已经注册好了JNI代码,相应的资源也已经加载完毕了。
为啥说它是累死累活的呢,因为几乎所有服务都是由SystemServer创建的。其中包括AMS,WMS,PMS等重要服务,都是运行在该进程上的,并且在该进程上注册到ServiceManager进程中。
各位有没有想过,我们每天滑动手机时的界面到底是什么。其实它和我们开发的手机程序一样,都是一个App。只不过它是由Android系统自动启动的。并且,它可以把我们的所有安装的App全都显示出来,仅此而已。
当我们点击Launcher上的App图标时,它会和AMS进行通信,AMS又和Zygote进行通信。Zygote进程fork出了一个新进程,并执行相关代码,从而我们编写的App就这样被创建了出来。
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