Zygote进程详解
来源:互联网 发布:c语言 char负值 编辑:程序博客网 时间:2024/06/05 15:31
Zygote进程是怎么启动的?
- Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。
- 在system\core\rootdir\init.rc文件中可以看到zygote的如下信息;
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd服务名称为:zygote启动该服务执行的命令: /system/bin/app_process命令的参数: -Xzygote /system/bin –zygote –start-system-serversocket zygote stream 660创建一个名为:/dev/socket/zygote 的 socket,类型为:stream,权限为:660onrestart:当服务重启时,执行该关键字后面指定的command总结:zygote要执行的程序便是system/bin/app_process,它的源代码在frameworks/base/cmds/app_process/app_main.cpp问题:可执行文件app_process运行后,通过ps验证其进程名为zygote,是如何转换的呢?解答:init.rc中定义中,参数为-Xzygote
- 通过adb shell ps |egrep '\<init\>|zygote|system_server' 命令可以查看到init,zygote,system_server之间的关系;
USER PID PPID VSIZE RSS WCHAN PC NAMEroot 1 0 688 328 c011bda0 00010be4 S /initroot 156 1 537700 23488 ffffffff 400d1d40 S zygotesystem 670 156 744476 75312 ffffffff 400d1c90 S system_serve
- init除了将zggote启动外,servicemanager、vold、rild、surfaceflinger等关键进程也都是通过init进程启动的
Zygote进程执行流程
- Zygote进程执行流程
1.zygote进程是运行的app_process,app_process在frameworks/base/cmds/app_process/下,程序的入口为该目录下app_main.cpp文件的main函数。2.在main函数中,会创建一个AppRuntime(AppRuntime是继承于AndroidRuntime)变量,然后调用它的start方法; runtime.start("com.android.internal.os.ZygoteInit",startSystemServer ? "start-system-server" : ""); 在init.rc中,zygote service设置了--start-system-server参数,因此startSystemServer为true;3.调用AndroidRuntime的start方法,在这个方法里主要做了三件事情: (1).AndroidRuntime::startVm()中,设置一些虚拟机的参数后,通过JNI_CreateJavaVM()启动虚拟机; (2).调用函数startReg注册JNI方法; (3).env->CallStaticVoidMethod,调用com.android.internal.os.ZygoteInit类的main()方法,正式进入到Java世界4.在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java的main函数中,做了三件事情: (1).调用registerZygoteSocket函数,创建了一个socket接口,用来和ActivityManagerService通信; <1>.registerZygoteSocket函数创建的socket接口是通过文件描述符(代表/dev/socket/zygote)来创建的; private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote" (环境变量) String env = System.getenv(ANDROID_SOCKET_ENV); int fileDesc = Integer.parseInt(env); sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc)); <2>.在init.c中service_start函数用于解析service命令,每一个service命令都会促使init进程调用fork函数来创建一个新的进程; 在新的进程里,都会通过create_socket(si->name, socket_type,si->perm, si->uid, si->gid);函数在/dev/socket目录下创建一个文件; 然后调用publish_socket(si->name, s);方法将描述符写到环境变量ANDROID_SOCKET_ENV中去 (2).调用startSystemServer函数来启动SystemServer组件; (3).调用runSelectLoopMode(在4.4上为runSelectLoop)函数,进入一个无限循环,便于在前面创建的socket接口上等待ActivityManagerService请求创建新的进程;5.startSystemServer函数中,调用Zygote.forkSystemServer函数来创建一个新进程来启动SystemServer组件; pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); // For child process if (pid == 0) { handleSystemServerProcess(parsedArgs);//新创建都进程都会执行 }6.在handleSystemServerProcess函数中,会调用closeServerSocket关闭socket描述符,接着调用RuntimeInit.zygoteInit函数来进一步启动SystemServer组件的操作; 子进程继承zygote的socket文件描述符,但用不到,因此会调用closeServerSocket关闭socket描述符;7.在RuntimeInit(frameworks/base/core/java/com/android/internal/os/RuntimeInit.java).zygoteInit函数中会执行两个操作: (1).调用nativeZygoteInit函数来执行一个Binder进程间通信机制的初始化工作; (2).会依次调用applicationInit(targetSdkVersion, argv);->invokeStaticMain(args.startClass, args.startArgs);函数,并抛出ZygoteInit.MethodAndArgsCaller异常;8.抛出的ZygoteInit.MethodAndArgsCaller异常会被ZygoteInit 的main函数捕获,调用caller.run(); 在run方法中将调用com.android.server.SystemServer类中的main方法; SystemServer类:frameworks/base/services/java/com/android/server/SystemServer.java
- Zygote的启动序列图如下:
- system_server是Zygote的分裂出的第一个子进程,即PPID为156(zygote的pid)的所有进程中他的PID编号最小
Zygote的监听和处理
- 在上面的第三步中,调用runSelectLoopMode(在4.4上为runSelectLoop)函数,进入一个无限循环,便于在前面创建的socket接口上等待ActivityManagerService请求创建新的进程;
- runSelectLoop函数中关键代码如下:
while (true) { try { fdArray = fds.toArray(fdArray); index = selectReadable(fdArray); //多路Select,响应Socket请求 } catch (IOException ex) { throw new RuntimeException("Error in select()", ex); }}
- 接收到Socket请求后,会fork出子进程,子进程调用handleChildProc方法,最终抛出RuntimeInit.invokeStaticMain异常,退出while(true)循环,进入到android.app.ActivityThread类的main方法执行;父进程调用handleParentProc方法,再次进入runSelectLoopMode中while(true)循环,准备接收下一个的请求事件。
- 和启动system_server进程时的调用堆栈非常相似,ZygoteInit类中的main方法中捕获MethodAndArgsCaller异常,并调用异常对象的run方法。即android.app.ActivityThread类的main方法,开始Activity的创建流程。
总结
- 系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作
- Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如包管理服PackageManagerService和应用程序组件管理服务ActivityManagerService。
- 当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程
- 启动zygote,进入Java世界
- zygote分裂出第一个进程system_server
- Zygote服务端监听fork子进程请求
0 0
- Zygote进程详解
- Zygote进程启动详解
- zygote进程
- Zygote详解
- zygote详解
- Android入门进阶教程(15)-进程创建zygote 详解
- Zygote进程简介
- Zygote进程简介
- Zygote进程功能笔记
- Zygote进程简介
- Zygote进程的启动
- Android zygote进程启动
- Android6.0 Zygote进程
- Zygote进程启动流程
- zygote 进程主要工作
- init进程与zygote进程
- 安卓Zygote详解
- Android Zygote 进程的启动
- 动态树||树链剖分(BZOJ1036)
- 四元数的表示
- 新装ubuntu12.04搜集一些碰到的问题
- 获取mp4文件信息2 - 计算电影图像宽度和高度
- matplotlib画图时的中文设置
- Zygote进程详解
- Java学习笔记之异常
- udp聊天室 带有注册功能
- 自定义ListAdapter使用时,不调用getView()的奇葩问题
- SQL语句简单整理
- Redis常用数据类型
- Google Earth与ArcGIS数据交互(四)
- 开通新博客,记录新生活
- 解决Qt中文乱码问题