这里会使用面试的视角来看这个问题,知其然即可,如果需要知其所以然还需要自己多下功夫
这道题呢,主要是考察你对framework的基本认识是怎样的,要是这个都答不好,基本上面试官是不想继续在framework这个话题上和你继续纠缠了。
对于zygote的理解这道题呢 我们通常可以从以下4个方面,由浅入深的解答
- Zygote的由来及作用
- Zygote的如何打开java世界大门
- native到java世界
- 开启桌面
- SystemServer的一些细节
- 创建其他子进程
- Zygote的一些经典问题
- 小结
能把前3点讲清楚基本上就得分了
请看到最后哦,会给出一张图来总结下这个问题
Zygote的由来
首先我们得回答一下什么是Zygote,以及它的作用
Zygote是个大名鼎鼎的进程,是Android系统启动过程中第一个Java进程的名称,一般称作孵化器。 它的作用简而言之就是
- 打开java世界的大门
- fork出 SystemServer 接受SystemServer的请求,fork出新的应用进程,如launch
- 共享资源
当我们手机按电源键系统启动时候就会开始创建zygote进程
由于安卓是Linux系统,启动之后开始进行** linux的加电**、加载linux内核,然后开启init进程,
init 是用户空间的第一个进程,init 进程通过解析init.rc 文件 并fork出一些比较重要的进程比如servicemanager(binder的管家)、还有我们今天的主角Zygote, Zygote又会创建system_server进程以及app进程。
流程如下:

这里得稍微提一下init进程,init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。
Zygote的如何开启java世界大门
Native到Java世界
有了zygote进程之后,就要开始发挥它的作用了。上面提到
- 打开Java世界的大门
- 孵化SystemServer 接受SystemServer的请求,fork出新的应用进程,如launch
- 共享资源
其中zygote如何完成从linux打开java世界的大门,这里是考察问题的重点 这个过程主要分为三步
- 启动虚拟机
- 注册Android的JNI函数
- 进入Java世界
如下图所示
Native层
在app_main.cpp中执行main()函数
- 构造AppRuntime对象,执行其start方法,启动Zygote进程
- 并创建Java虚拟机、注册一系列的JNI函数将Java和Native层关联起来
- 通过JNI调用Java方法,执行com.android.internal.os.ZygoteInit 的 main 方法
Java
- 完成Native层切换到Java层,反射执行ZygoteInit.java main()函数 fork system_server进程,system_server为所有App提供服务包括ams、wms等,可以说是系统的核心进程之一
- 预加载进程公共资源类以及资源(后续fork的子进程可以复用,加快后续进程创建速度)
- 使用registerZygoteSocket方法创建服务器端Socket,zygote便会将自身挂起,并循环监(runSelectLoop)听来自system_server创建子进程的Socket请求。
这样就从linux世界来到了java世界,此时要注意 zygote已经进入loop循环休眠,交给systemserver来进行后续的处理
开启桌面
不过此时你的手机可能还是下图这个状态,并没有到熟悉的桌面,

这里还需要zygotefork出来的systemServer来帮忙进入桌面launcher 我们再来仔细看下这块
- Zygote fork出systemserver,进入休眠。
- SystemServer负责启动和管理整个Java frameWork。SystemServer进程在开启的时候,会初始化AMS、WMS、PMS等关键服务。同时会加载本地系统的服务库,调用createSystemContext()创建系统上下文,创建ActivityThread及开启各种服务等等。
- systemserver中创建AMS服务(systemReady),请求systemserver向zygote fork launcer进程 从而进入桌面
SystemServer的一些细节
这里再补充一些systemserver的相关细节,当你聊到这里时候,面试官通常会问一下SystemServer,这里我们需要抓住3个要点
- 是Zygote孵化的第一个进程
- 负责启动核心系统服务,包含ActivityManager,WindowManager,PackageManager,PowerManager等
- 触发Launcher启动
我们来看下核心服务这里
System Server负责启动核心系统服务,主要分为3大类,
1.startBootstrapServices 启动引导服务 比如AMS(actvitymanagerservice)、PMS电池和包管理服务、DisplayManagerService、传感器服务等
2.startCoreServices 启动核心服务 如 电池状态管理服务、驱动加载服务、webview升级服务等
3.startOtherServices 启动其他服务 如 蓝牙服务、窗口管理服务wms、电话服务等
AMS中有个重要的方法systemReady,触发AMS启动 Launcher Activity(不同源码版本这里有些差异这里不再赘述),
从这里从通过socket唤起沉睡的zygote去创建launcer进程,从而进入桌面
Zygote创建其他子进程
当按下电源键到进入桌面这个过程zygote的创建以及作用介绍一遍之后, 面试官可能会继续问下,在桌面上点击比如微信图标
zygote的过程,这里其实跟加载桌面进程有异曲同工之妙,如下图
- Launcher App 收到点击请求,会执行startActivity,这个命令会通过Binder传递给system_server进程里的AMS(ActivityManagerService)模块
- AMS 发现对应的微信进程并没有启动,于是通过Socket发送创建微信进程的请求给Zygote
- Zygote 收到Socket请求后,fork 微信进程并执行对应的入口函数,之后就会显示出微信的界面了
Zygote是一个C/S模型,Zygote进程作为服务端,它主要负责创建Java虚拟机,加载系统资源,启 动SystemServer进程,以及在后续运行过程中启动普通的应用程序,其他进程作为客户端向它发 出“孵化”请求,而Zygote接收到这个请求后就“孵化”出一个新的进程。比如,当点击Launcher里 的 应用程序图标去启动一个新的应用程序进程时,这个请求会到达框架层的核心服务 ActivityManagerService中,当AMS收到这个请求后,它通过调用Process类发出一个“孵化”子进 程的Socket请求,而Zygote监听到这个请求后就立刻fork一个新的进程出来
runSelectLoop Zygote采用高效的I/O多路复用机制,保证在没有客户端连接请求或数据处理时休眠,否则响应客户端的请求。
2个经典问题
当你聊到这里基本上是大致说清楚的zygote了,这时候,面试官可能会继续追问,看看你对一些细节是否有些了解下面是2个比较经典的问题,这里使用问答机制
- Zygote的IPC通信机制为什么不采用binder?如果采用binder的话会有什么问题么?
fork机制是单线程fork,也就是说fork出来的子进程只有一个线程,如果使用binder机制去实现进程间的通讯,因为binder机制有binder线程池,线程之间的安全由锁控制,所以当fork出现的子线程如果只有一个线程时,很可能会引起死锁,主要答出关键点单线程、死锁基本就ok了
- 为什么后续进程由Zygote去fork进程,而不是由SystemServer去fork?
由Zygote去专门处理fork进程和进程的资源,比如Android虚拟机和主题加载,JNI函数注册等,职责和分工更加明确,SystemServer进程除了需要启动其他系统服务,比如AMS,PMS等,还需要注册服务等等工作,而且SystemServer进程也是通过binder线程池去和其他进程通讯,所以由Zygote去fork进程,也是因为这样,所以才起了这个名字Zygote(孵化器) 。
小结
答题得分点
- zygote initrc解析来的
- zygote 作用,如何开启java世界的大门
- 如何跟systemserver配合的 打开桌面launcer进程以及后续点击应用启动新的应用进程
- 经典问题