Zygote工作流程分析
Zygote
接收客户端创建进程的请求,使用JNI调用linux fork函数创建进程。
Zygote是在Init进程中作为Service被启动的。Zygote进程的主体是:ZygoteInit。
Zygote进程的启动可以参考前篇:Android系统启动过程
http://www.cnblogs.com/bastard/archive/2012/08/28/2660389.html
系统启动过程如下图:
下面主要看看Zygote是如何进行工作的。
一 Zygote工作流程
主函数:
public static void main(String argv[]) {……// Registers a server socket for zygote command connectionsregisterZygoteSocket();/*** Runs the zygote process's select loop. Accepts new connections as* they happen, and reads commands from connections one spawn-request's* worth at a time.*/runSelectLoopMode(); //loop中 }
消息循环是runSelectLoopMode:
private static void runSelectLoopMode() throws MethodAndArgsCaller { … …while (true) {int index;//异步方式 获取ZygoteConnection Command fdArray = fds.toArray(fdArray);index = selectReadable(fdArray);if(index == 0) {//读取新的ZygoteConnection SocketZygoteConnection newPeer = acceptCommandPeer();peers.add(newPeer);fds.add(newPeer.getFileDesciptor());} else {//处理ZygoteConnection Commandboolean done;done = peers.get(index).runOnce();} } }
过程如下图所示:
1 ZygoteConnection Command 接收
在ZygoteInit的 main函数中
public static void main(String argv[]) {……// Registers a server socket for zygote command connectionsregisterZygoteSocket();/*** Runs the zygote process's select loop. Accepts new connections as* they happen, and reads commands from connections one spawn-request's* worth at a time.*/runSelectLoopMode(); //loop中 }//registerZygoteSocket注册了Server 端Socket监听ZygoteConnection:private static void registerZygoteSocket() {//” ANDROID_SOCKET_zygote”String env = System.getenv(ANDROID_SOCKET_ENV);fileDesc = Integer.parseInt(env);//private static LocalServerSocket sServerSocket;if (sServerSocket == null) {sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc));} }
使用到了LocalServerSocket进行通信,具体如何进行请看源码。
2 ZygoteConnection Command处理
在循环中done = peers.get(index).runOnce();——> ZygoteConnection runOnce
boolean runOnce( ) {Arguments parsedArgs = null;FileDescriptor[] descriptors;//Reads one start command from the command socket.args = readArgumentList();descriptors = mSocket.getAncillaryFileDescriptors();//创建/Forks a new VM instance /process.//使用Jni 调用nativeForkpid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids, parsedArgs.debugFlags, rlimits);//返回两次if (pid == 0) {// in child serverPipeFd = null;handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);// should never get here, the child is expected to eitherreturn true;} else {// in parent...pid of < 0 means failurechildPipeFd = null;return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);} }
3 Zygote创建新进程的执行
从上面的代码中可以看到创建进程之后返回:
子进程:handleChildProc
父进程:handleParentProc
我们关心的是子进程的执行,继续到handleChildProc中。
// Handles post-fork setup of child proc private void handleChildProc(Arguments parsedArgs,...){……if (parsedArgs.runtimeInit) {if (parsedArgs.invokeWith != null) { //通过系统调用执行进程WrapperInit.execApplication(parsedArgs.invokeWith,parsedArgs.niceName, parsedArgs.targetSdkVersion,pipeFd, parsedArgs.remainingArgs);} else {//通过寻找到相应目标类的main()函数并执行RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs);}}…… }
看到子进程的执行有两种方式:
WrapperInit.execApplication和RuntimeInit.zygoteInit:
1)通过系统调用的方式执行进程 WrapperInit.execApplication:
public static void execApplication(……) {……Zygote.execShell(command.toString()); }public static void execShell(String command) {// using the exec() system callnativeExecShell(command); }
2)通过寻找到相应目标类的main()函数并执行 RuntimeInit.zygoteInit:
// The main function called when started through the zygote process. public static final void zygoteInit( ){zygoteInitNative();applicationInit(targetSdkVersion, argv); }private static void applicationInit( ) {// Remaining arguments are passed to the start class's static maininvokeStaticMain(args.startClass, args.startArgs); }通过RuntimeInit调用startClass的main函数。
为何两种方式?可以参考下面文章:
http://blog.csdn.net/21cnbao/article/details/7791254
以上是Zygote大概简要的工作流程,要深入了解进程创建过程还不行,以上两种方式执行新创建的进程有何区别,
还得熟悉Android,Linux 及其Fork的一些知识和原理。
linux fork可以参考我转载的文章:
http://www.cnblogs.com/bastard/archive/2012/08/31/2664896.html
了解了Zygote大概工作流程,如果我们要创建进程该如何告知Zygote呢?
在StartActivity如果是启动新的应用就会创建该应用的进程,下面我们可以看一下StartActivity时创建进程的过程。
二 应用程序进程的创建过程
启动一个新的应用程序为例,启动新的应用程序时候是以startActivity的方式进行,这个过程大致如下图:
在启动应用程序的时需要创建应用程序的进程,执行到:
ActivityManagerService的startProcessLocked函数中;看一下这个函数过程:
private final void startProcessLocked(ProcessRecord app,String hostingType, String hostingNameStr) {// Start the process. It will either succeed and return a result containing// the PID of the new process, or else throw a RuntimeException.Process.ProcessStartResult startResult =Process.start("android.app.ActivityThread",app.processName, uid, uid, gids, debugFlags,app.info.targetSdkVersion, zygoteArgs); }
到了Process这个类:Tools for managing OS processes.
public static final ProcessStartResult start(…… ) {return startViaZygote(processClass, niceName, uid, gid, gids,debugFlags, targetSdkVersion, zygoteArgs); }//Starts a new process via the zygote mechanism. private static ProcessStartResult startViaZygote(…… ) {synchronized(Process.class) {ArrayList<String> argsForZygote = new ArrayList<String>();//参数设置// --runtime-init, --setuid=, --setgid=,……//--runtime-init这里决定上面所提到创建新的进程的启动方式argsForZygote.add("--runtime-init"); argsForZygote.add("--setuid=" + uid);argsForZygote.add("--setgid=" + gid);//……argsForZygote.add(processClass);for (String arg : extraArgs) {argsForZygote.add(arg);} return zygoteSendArgsAndGetResult(argsForZygote);}}
//Sends an argument list to the zygote process, which starts a new child //and returns the child's pid private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args) {//open socket to Zygote process if not already openopenZygoteSocketIfNeeded();//write ArgumentsZygoteWriter.write(Integer.toString(args.size()));sZygoteWriter.newLine();sZygoteWriter.flush();……}
通过上面这一段代码,向Zygote发送创建进程的请求,设置相关的参数。
其中有argsForZygote.add("--runtime-init"); 决定新创建进程的启动方式为RuntimeInit.zygoteInit方式启动:
找到目标类main函数执行。
processClass为"android.app.ActivityThread",将是进程创建之后执行的类,执行其中的main函数。
联系上面的流程:
即创建进程后执行到RuntimeInit.zygoteInit中:(直接找到目标类的main函数调用不是系统调用)
// The main function called when started through the zygote process. public static final void zygoteInit( ){applicationInit(targetSdkVersion, argv); }private static void applicationInit( ) { //后将执行:ActivityThread的main函数,启动界面。invokeStaticMain(args.startClass, args.startArgs);}
ActivityThread就是应用程序的主线程的入口。
以上便是Zygote工作流程和启动应用程序创建进程大概简单过程,其中所涉及到知识和框架比较多,还需要去理解linux fork知识和原理,
进程概念,Android进程通信机制Binder,Activity启动过程等。这里仅简单的从代码上做流程分析。
参考文档:
http://blog.csdn.net/luoshengyang/article/details/6689748
Zygote工作流程分析相关推荐
- Framework原理分析之——Zygote进程流程分析
在启动Zygote进程的分析中,我们知道其实是通过系统调用fork()函数来创建一个进程,然后执行Zygote.rc中的执行文件,从而开始Zygote进程业务. 本篇文章我们就来分析大名鼎鼎的Zygo ...
- 16.U-boot的工作流程分析-2440
16.U-boot的工作流程分析-2440 分析的流程: 程序入口 第一阶段程序分析 第二阶段程序分析 2440开发板: 1.uboot的入口: 要看uboot工程的入口,首先打开顶层目录的Makef ...
- K8S架构设计及工作流程分析
Kubernetes架构设计 核心组件 api server 功能 controller manager 负责维护集群的状态 scheduler 负责资源的调度按照预定的调度策略将Pod调度到相应的机 ...
- kafka的基本概念和工作流程分析
为什么需要消息队列 周末无聊刷着手机,某宝网APP突然蹦出来一条消息"为了回馈老客户,女朋友买一送一,活动仅限今天!".买一送一还有这种好事,那我可不能错过!忍不住立马点了去.于是 ...
- 【转载】csr8670--sink工程的大致工作流程分析(以speaker为例)二
csr8670--sink工程的大致工作流程分析(以speaker为例)二 1.编解码任务的初始化 继续接着流程一分析: 1.1 当连接初始化完成之后,如下所示会调用编解码的初始化任务:这个编解码的任 ...
- 【SemiDrive源码分析】【X9芯片启动流程】14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析
[SemiDrive源码分析][X9芯片启动流程]14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析 一.SafetyOS 工作流程分析 1. ...
- 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析
Okhttp系列文章: 你想要的系列:网络请求框架OkHttp3全解系列 - (一)OkHttp的基本使用 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析 你想 ...
- Android 7.0 WifiMonitor工作流程分析
2019独角兽企业重金招聘Python工程师标准>>> 在wifi启动扫描的分析过程中,出现了多次WifiMonitor的操作,在此分析一下这个函数是如何工作的. 在Android的 ...
- NSURLSession使用说明及后台工作流程分析
NSURLSession简介 NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的.在程序在前台时,NSURLSession与NSURLConnect ...
最新文章
- 【Java】基本二叉搜索树讲解
- try()...catch()的用法
- NR 5G 身份标识
- 将VMware Workstation 12 Pro的虚拟网卡修改为自己希望的IP网段
- 掌握这 20 个容器实战技巧!
- AI繁荣下的隐忧——Google Tensorflow安全风险剖析
- JVM调优总结(四)-垃圾回收面临的问题
- 如何在SAP CRM Fiori My Task应用里创建task
- 哪种语言 连接 oracle,Go语言连接Oracle(就我这个最全)
- [jQuery基础] jQuery对象 -- 属性操作
- html搜题软件,大学搜题app哪个好_大学好的搜题软件_大学搜题免费
- Xcode CoreData 存储报错问题。
- rarlinux基于linux-x64
- 课程设计(银行叫号机系统)
- Ice通信之Ice::Application
- 开关电源EMI整改实例(方法)。
- 基于SpringBoot的网上电影票购买系统设计与实现
- 鸡与 兔有几条腿的问题
- 计量经济学笔记3-Eviews操作-多元线性回归
- 揭密巴西Banrisul银行网站遭遇5小时劫持的原因