Android系统的启动流程(开机流程)
上图,先大致了解一下Android点击电源键开机到创建出system_server进程的流程,里面细化的子流程和system_server之后发生的事情我们后面再讲:
Boot Rom:当电源键按下时,引导芯片就会启动,引导芯片代码会从预定义的地方开始执行(代码存在Rom),加载引导程序BootLoader到RAM。换句话说,就是启动的时候,会把引导程序代码由ROM中移动到RAM中,再去执行引导程序BootLoader。
ROM可以简单理解为硬盘,断电后内部的数据是不会丢失的。
RAM可以简单理解为运行时内存,断电后内部的数据就会丢失。
具体他们的含义是什么,这里就不再赘述,大家感兴趣自己去查一下吧
BootLoader:BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。BootLoader执行后,就会启动我们的操作系统。
idle进程:当操作系统启动后,就会启动系统的第一个进程,idle进程,它的进程号为0。当这个进程启动后,就会再次启动另外两个进程,一个是kthreadd进程,一个是init进程(当idle进程被启动后,会在系统文件中寻找 init.rc 文件,用来启动init进程)。
kthreadd进程:它跟idle一样,都是位于内核层。它主要是用来创建内核工作线程、软中断线程等内核相关的工作,我们不需要太过关注。
init进程:idle进程属于nativer层。它的主要工作是初始化进程管理,内存管理,加载Binder Driver、Display、Camera Driver等。它是首个开辟用户空间的进程,是用户空间的鼻祖
init进程:它的进程号为1。在init进程内部,会fork出我们所熟知的一个进程:zygote进程。
zygote进程:又名孵化器,它是java进程的鼻祖。在zygote中,它第一个fork出来的进程是SystemServer进程。同时,我们设备上的app进程都是由zygote进程来创建的。
SystemServer进程:Android中常用系统服务(AMS/WMS/PMS )都是由SystemServer这个进程启动的,所以它相当重要,SystemServer这个我们后面的篇幅再细说。
Zygote/SystemService启动流程
下面我们跟进一下源码(以下源码基于Android 11),看一下从init进程开始,到Zygote进程和SystemService进程创建的过程,先看图:
启动init进程过程中,会进入system/core/init/init.cpp文件的main()方法中,关键代码如下:
1、执行frameworks/base/cmds/app_process/app_main.cpp中的main()方法**(此时处于init进程中)**
1、初始化AndroidRuntime(Android运行时环境)
2、在main函数的最后,通过调用上面创建的AndroidRuntime对象的**start(“com,android.internal.os.ZygoteInit”, args, zygote)**方法,启动我们Android运行时环境
2、执行runtime.start()方法启动zygoteInit,它做了如下几个关键事情。我们进入start方法内部看看里面写什么东西:
1、创建虚拟机、注册jni方法
上面这段代码里,相关地方注释也就写得很明白了,在这里面也看出,一个进程,内部包含一个虚拟机。
2、当我们注册完jni,在下面的代码开始使用jni方法调用com.android.inter.os.ZygoteInit.main()方法,由此进入java世界:
为什么要用jni方法来调用ZygoteInit的main()方法呢?因为zygote是java进程的鼻祖,而我们平时开发的app都是属于java层的代码,想要从native层进入java层,就需要用到jni,我们可以将jni理解为native层和java层之间的桥梁。
3、执行ZygoteInit.main()方法,它做了如下几个关键事情。我们进入ZygoteInit.main()方法内部看看里面写什么东西:
1、执行preload()方法预加载信息,这些预加载信息包括了一部分framework的资源,以及一部分常用的java类。这部分预加载的信息,在后面创建的进程都是可以直接用的。所以这里预加载的作用就是加快了应用进程的启动速度
2、创建zygote的socket服务
在这里使用的socket进行进程之间的通信,为什么不用Binder呢?事实上,代码执行到这,Binder还没开始初始化。
3、通过fork创建SystemServer进程
在这里通过调用forkSystemServer()方法,以fork的形式创建了system_setver进程。在这段代码中也可以看到,执行r.run()方法,run方法内部会执行SystemServer的main方法,我们等会再说SystemServer的main方法里面做啥什么吧,,,
4、当我们继续往main方法下面走,就会执行zygoteServer.runSelectLoop()方法,使zygote进入无限循环,等待AMS给他发消息,从而创建进程。这里还有一个点要注意:为什么我们要用zygote去fork应用进程,而不是用init进程去fork呢?—首先我们要知道,init进程除了fork出zygote进程外,还会创建很多其他进程,而且这些进程我们应用进程都是不需要的。那为什么不放在SystemServer进程中fork应用进程呢,因为SystemServer里会启动很多的系统服务,像AMS/PMS/WMS等等,大大小加起来也有100个左右了,而且这些服务是所有哟应用进程公用的,通过进程通信就可以访问。