在Linux系统中,所有的进程都是 init 进程的子孙进程,即所有进程都是直接或者间接地由 init 进程 fork 出来的。 Zygote 进程也不例外,它是在系统启动的过程,由 init 进程创建的。
Zygote进程
Zygote进程在系统启动的时候就会产生,它会完成虚拟机的初始化,库的加载,预制类库和初始化的操作。如果系统需要一个新的虚拟机实例,它会迅速复制自身,以最快的数据提供给系统。对于一些只读的系统库,所有虚拟机实例都和 Zygote 共享一块内存区域。
Zygote进程是所有APK应用进程的父进程。可以在 init.rc 中配置 Zygote 启动参数(注册服务、指定可执行文件路径、指定虚拟机路径、重启时触发动作等等)。
1. 注册zygote用的Socket
Socket 端口用于接收启动新进程的命令。
Socket 中有两种方式去触发 Socket 数据读操作:
- 阻塞式读操作:使用 listen() 监听某个端口,然后调用 read() 从这个端口上读取数据。
-
非阻塞式读操作:( LocalServerSocket )
- 使用 select() 函数将需要监测的文件描述符作为 select() 函数的参数
- 然后当该文件描述符上出现新的数据后自动触发一个中断,然后在中断处理函数中再去读指定文件描述符上的数据。
2. preloadClass 和 preloadResources 并强制执行一次GC
preloadClass(预加载类):预加载的类放在 preloaded-classes 文件中,该文件保存需要预加载的类的全限定名称列表, preload 工具将加载时间超过1250微秒的类加入到这个列表文件中。(这也是导致android开机慢的原因)
preloadResources(预加载资源):主要加载 framework-res.apk 中的资源。我们经常用的 com.android.R.xxx 资源是系统默认资源,由zygote加载。
3. startSystemServer() ,启动 system_server 进程
创建Java中系统Service所驻留的进程 system_server ,该进程是framework的核心。(如果它死了,就会导致 Zygote 自杀。)
SystemServer进程
在Android的运行环境中扮演着“神经中枢”的作用,APK应用中能够直接交互的大部分系统服务都在该经常中运行,如:WmS、AmS、PmS等,这些系统服务都是以一个线程的方式存在于 SystemServer 进程中。
4. 调用 runSelectLoopMode() 函数
Zygote从 startSystemServer 返回后,进入函数 runSelectLoopMode 。
之前注册Socket的用途有了用处:
- 处理客户连接和客户请求(其中客户在zygote中使用 ZygoteConnection 表示)
- 客户的请求由 ZygoteConnection 的 runOnce 来处理。
runOnce 创建新进程,如AmS通过Socket请求创建新进程打开一个App。
--------整理自网络