Zygote和System进程的启动过程
##init脚本的启动
+------------+ +-------+ +-----------+
|Linux Kernel+--> |init.rc+-> |app_process|
+------------+ +-------+ +-----------+
create and public
server socket
linux内核加载完成后,运行init.rc脚本
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server socket zygote stream 666
- /system/bin/app_process Zygote服务启动的进程名
- --start-system-server 表明Zygote启动完成之后,要启动System进程。
- socket zygote stream 666 在Zygote启动时,创建一个权限为666的socket。此socket用来请求Zygote创建新进程。socket的fd保存在名称为“ANDROID_SOCKET_zygote”的环境变量中。
##Zygote进程的启动过程
create rumtime
+-----------+ +----------+
|app_process+----------> |ZygoteInit|
+-----------+ +-----+----+
|
|
| registerZygoteSocket()
|
+------+ startSystemServer() |
|System| <-------+ |
+------+ fork | runSelectLoopMode()
|
v
app_process进程
/system/bin/app_process
启动时创建了一个AppRuntime对象。通过AppRuntime对象的start方法,通过JNI调用创建了一个虚拟机实例,然后运行com.android.internal.os.ZygoteInit类的静态main方法,传递true(boolean
startSystemServer)参数。
ZygoteInit类
ZygoteInit类的main方法运行时,会通过registerZygoteSocket方法创建一个供ActivityManagerService使用的server socket。然后通过调用startSystemServer方法来启动System进程。最后通过runSelectLoopMode来等待AMS的新建进程请求。
- 在registerZygoteSocket方法中,通过名为ANDROID_SOCKET_zygote的环境获取到zygote启动时创建的socket的fd,然后以此来创建server socket。
- 在startSystemServer方法中,通过Zygote.forkSystemServer方法创建了一个子进程,并将其用户和用户组的ID设置为1000。
- 在runSelectLoopMode方法中,会将之前建立的server socket保存起来。然后进入一个无限循环,在其中通过selectReadable方法,监听socket是否有数据可读。有数据则说明接收到了一个请求。 selectReadable方法会返回一个整数值index。如果index为0,则说明这个是AMS发过来的连接请求。这时会与AMS建立一个新的socket连接,并包装成ZygoteConnection对象保存起来。如果index大于0,则说明这是AMS发过来的一个创建新进程的请求。此时会取出之前保存的ZygoteConnection对象,调用其中的runOnce方法创建新进程。调用完成后将connection删除。 这就是Zygote处理一次AMS请求的过程。
##System进程的启动
+
|
|
v fork()
+--------------+
|System Process|
+------+-------+
|
| RuntimeInit.zygoteInit() commonInit, zygoteInitNative
| init1() SurfaceFlinger, SensorServic...
|
|
| init2() +------------+
+-------> |ServerThread|
| +----+-------+
| |
| | AMS, PMS, WMS...
| |
| |
| |
v v
System进程是在ZygoteInit的handleSystemServerProcess中开始启动的。
- 首先,因为System进程是直接fork Zygote进程的,所以要先通过closeServerSocket方法关掉server socket。
- 调用RuntimeInit.zygoteInit方法进一步启动System进程。在zygoteInit中,通过commonInit方法设置时区和键盘布局等通用信息,然后通过zygoteInitNative方法启动了一个Binder线程池。最后通过invokeStaticMain方法调用SystemServer类的静态Main方法。
- SystemServer类的main通过JNI调用cpp实现的init1方法。在init1方法中,会启动各种以C++开发的系统服务(例如SurfaceFlinger和SensorService)。然后回调ServerServer类的init2方法来启动以Java开发的系统服务。
- 在init2方法中,首先会新建名为"android.server.ServerThread"的ServerThread线程,并调用其start方法。然后在该线程中启动各种Service(例如AMS,PMS,WMS等)。启动的方式是调用对应Service类的静态main方法。
- 首先,AMS会被创建,但未注册到ServerManager中。然后PMS被创建,AMS这时候才注册到ServerManager中。然后到ContentService、WMS等。 注册到ServerManager中时会制定Service的名字,其后其他进程可以通过这个名字来获取到Binder Proxy对象,以访问Service提供的服务。
- 执行到这里,System就将系统的关键服务启动起来了,这时候其他进程便可利用这些Service提供的基础服务了。
- 最后会调用ActivityManagerService的systemReady方法,在该方法里会启动系统界面以及Home程序。
##Android进程启动
+----------------------+ +-------+ +----------+ +----------------+ +-----------+
|ActivityManagerService| |Process| |ZygoteInit| |ZygoteConnection| |RuntimeInit|
+--------------+-------+ +---+---+ +-----+----+ +-----------+----+ +------+----+
| | | | |
| | | | |
startProcessLocked() | | | |
+---------------> | | | | |
| start() | | | |
| "android.app.ActivityThread" | | |
+-----------------> | | | |
| | | | |
| | | | |
| |openZygoteSocketIfNeeded() | |
| +------+ | | |
| | | | | |
| | <----+ | | |
| | | | |
| |sZygoteWriter.write(arg) | |
| +------+ | | |
| | | | | |
| | | | | |
| | <----+ | | |
| | | | |
| +--------------> | | |
| | | | |
| | |runSelectLoopMode() | |
| | +-----------------+ | |
| | | | | |
| | | <---------------+ | |
| | | acceptCommandPeer() |
| | | | |
| | | | |
| | | runOnce() | |
| | +------------------> | |
| | | |forkAndSpecialize()
| | | +-------------+ |
| | | | | |
| | | | <-----------+ |
| | | | handleChildProc()
| | | | |
| | | | |
| | | | |
| | | | zygoteInit() |
| | | +-------------> |
| | | | |
| | | | |in^okeStaticMain()
| | | | +---------------->
| | | | |("android.app.ActivityThread")
| | | | |
| | | | |
+ + + + +
- AMS向Zygote发起请求(通过之前保存的socket),携带各种参数,包括“android.app.ActivityThread”。
- Zygote进程fork自己,然后在新Zygote进程中调用RuntimeInit.zygoteInit方法进行一系列的初始化(commonInit、Binder线程池初始化等)。
- 新Zygote进程中调用ActivityThread的main函数,并启动消息循环。
Zygote和System进程的启动过程的更多相关文章
- Zygote和System进程的启动过程、Android应用进程启动过程
1.基本过程 init脚本的启动Zygote Zygote进程的启动 System进程的启动 Android应用进程启动过程 2.init脚本的启动 +------------+ +-------+ ...
- Android4.4 Framework分析——Zygote进程的启动过程
Android启动过程中的第一个进程init.在启动过程中会启动两个关键的系统服务进程ServiceManager和Zygote. 本文要介绍的就是Zygote进程的启动,Zygote俗称孵化器,专门 ...
- Zygote及System进程启动
1. init 根据init.rc 运行 app_process, 并携带‘--zygote' 和 ’--startSystemServer' 参数. 2. AndroidRuntime.cpp: ...
- Android 儿子Activity在启动过程中的流程组件 && 儿子Activity在一个新的进程组件启动过程
1.儿子Activity在启动过程中的流程组件 在Android Activity启动过程http://blog.csdn.net/jltxgcy/article/details/35984557一文 ...
- 笔记:Zygote和SystemServer进程启动过程
简述 Android设备启动过程中,先是Linux内核加载完,接着Android中的第一个进程init启动,它会启动一些需要开机启动的进程. Zygote就是进程init启动起来的.Android中所 ...
- ZT 第9章 Framework的启动过程
所在位置: 图书 -> 在线试读 -> Android内核剖析 第9章 Framework的启动过程 9.3 zygote的启动 前面小节介绍了Framework的运行环境,以及Dalvi ...
- Android系统启动流程(四)Launcher启动过程与系统启动流程
此前的文章我们学习了init进程.Zygote进程和SyetemServer进程的启动过程,这一篇文章我们就来学习Android系统启动流程的最后一步:Launcher的启动流程,并结合本系列的前三篇 ...
- Android源码——Activity组件的启动过程
根Activity启动过程 Launcher启动MainActivity的过程主要分为6个步骤: 一.Launcher向ActivityManagerService发送一个启动MainActivity ...
- Android系统启动流程(二)解析Zygote进程启动过程
1.Zygote简介 在Android系统中,DVM(Dalvik虚拟机).应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器.它通过 ...
随机推荐
- ansible基本模块-shell
ansible XXX -m shell -a "XXX"
- 格子刷油漆(dp)-----------蓝桥备战系列
标题:格子刷油漆 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如图1所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但 ...
- BZOJ - 2115 独立回路 线性基
题意:给定一个图集\((V,E)\),求路径\(1...n\)的最大异或和,其中重复经过的部分也会重复异或 所求既任意一条\(1...n\)的路径的异或和,再异或上任意独立回路的组合的异或和(仔细想想 ...
- UESTC - 1652 递推方程
方程很简单,每一公里往上推就行 WA了2发,忘了单通道时的特判,还有n m傻傻分不清,忘了fixed什么的我好弱啊QAQ.. #include<bits/stdc++.h> #define ...
- Two Sum [easy] (Python)
由于题目说了有且只有唯一解,可以考虑两遍扫描求解:第一遍扫描原数组,将所有的数重新存放到一个dict中,该dict以原数组中的值为键,原数组中的下标为值:第二遍扫描原数组,对于每个数nums[i]查看 ...
- mysql 锁问题 (相同索引键值或同一行或间隙锁的冲突)
1.使用相同索引键值的冲突 由于mysql 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但如果是使用相同的索引键,是会出现锁冲突的.设计时要注意 例如:city表city_ ...
- MAC 下 STF 的环境搭建和运行
STF --WEB 端批量移动设备管理控制工具 安装各种包 (首先安装Macport,因为后面需要用到port:http://www.ccvita.com/434.html) linux的基本包安装, ...
- dockerfile 语法
基本语法格式:INSTRUCTION arguments (指令+参数)不分大小写 注释格式:# 注释 第一个指令必须是FROM,标示使用什么镜像 1.解析器指令 解析器指令是可选的,并且影响处理Do ...
- 创建本地maven仓库
1.首先从下面地址下载nexus-oss-webapp-2.3.1-01 http://pan.baidu.com/s/1pKOLdbH 2.修改配置文件: 打开:*nexus-oss-webapp- ...
- 白话SpringCloud | 第八章:分布式配置中心的服务化及动态刷新
前言 上一章节,简单介绍了分布式配置中心Spring Cloud Config的使用.同时,我们也遗漏了一些问题,比如如何配置实时生效,当服务端地址变更或者集群部署时,如何指定服务端地址?回想,在服务 ...