系统源码路径:http://www.androidos.net.cn/sourcecode
在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的;
因为Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程;
也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。
大致流程可分为:
init进程 –> Zygote进程 –> SystemServer进程 –>各种应用进程
init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;
Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;
SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境.
接下来咱们边看源码边详细分析它们的流程关系。
这里我们以Android 10 为例,在系统启动脚本 system/core/rootdir/init.rc 文件中,我们可以看到启动Zygote进程的脚本命令:
从上面的代码可以看出, 在 system/core/rootdir 目录下系统不止一个zygote*.rc文件:
每个文件里的启动zygote方式差不多,下面就以init.zygote64_32.rc为例看下里面的代码:
看到上面的代码估计你也能猜出来另外三个zygote*.rc是怎样的,具体选择哪个文件和编译时定义的ro.zygote值有关。
前面的关键字service告诉init进程创建一个名为"zygote"的进程,这个zygote进程要执行的程序是/system/bin/app_process64,后面是要传给app_process64的参数。
接下来的"class main"表示执行system/bin/app_process64后调用main方法,socket关键字表示这个zygote进程需要一个名称为"zygote"的socket资源,这样,系统启动后,我们就可以在/dev/socket目录下看到有一个名为zygote的文件,onrestart关键字表示这个zygote进程重启时需要执行的命令,最后一个writepid关键字表示需要重写系统pid。
通过上面我们知道Zygote进程要执行的程序便是app_process64了,它位于 frameworks/base/cmds/app_process/app_main.cpp 文件中,入口函数是main。(app_process64 or app_process32 都是通过 frameworks/base/cmds/app_process 编译出来的,只是由编译环境来决定生成那个文件),在分析zygote进程启动之前,来看看它启动的时序图
下面就看看从app_process64到Zygote启动具体流程:
1、在 app_main.cpp 的 main 函数中调用AndroidRuntime.start
由于我们在init.zygote64_32.rc文件中,设置了app_process启动参数–zygote和–start-system-server,因此,在main函数里面,最终会执行下面语句:
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
2、通过 AndroidRuntime.start 调用 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 的 main 函数
在这个方法中主要干了6件事:
3、调用ZygoteInit.forkSystemServer启动system server
这里可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是子进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。
在SystemServer中主要做了5件事:1、初始化设置一些系统属性;2、准备MainLooper;3、初始化system context对象;4、创建system service manager;5、调用startBootstrapServices(),startCoreServices(),startOtherServices()启动各种service
到这里Zygote进程就启动完成了,这里简单总结一下: