文中的源代码版本为api23

Zygote进程启动流程分析

先说结论,zygote进程启动过程中主要做了下面这些事情:

  1. 启动DVM虚拟机
  2. 预加载部分资源,如一些通用类、通用资源、共享库等
  3. 启动system_server进程
  4. 创建一个ServerSocket,并进入死循环监听Socket消息。

我们知道在Android操作系统中,zygote进程占据着非常重要的地位,所有应用进程都是由zygote进程孵化而来。zygote进程启动的起点在app_main.cppmain函数中(对这一点有疑问的童鞋可以参考这篇博客Android系统启动流程(一)解析init进程启动过程),接下来,我们就以该函数为入口点,一步步分析zygote的启动流程。

app_main

main函数的入参读取自init.rc文件: -Xzygote /system/bin --zygote --start-system-server main函数的主要工作是解析部分参数,最终调用AppRuntime.start方法

int main(int argc, char* const argv[])
{//...AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// Process command line arguments// ignore argv[0]argc--;argv++;//...int i;for (i = 0; i < argc; i++) {if (argv[i][0] != '-') {break;}if (argv[i][1] == '-' && argv[i][2] == 0) {++i; // Skip --.break;}runtime.addOption(strdup(argv[i]));}//...++i;  // Skip unused "parent dir" argument.while (i < argc) {const char* arg = argv[i++];if (strcmp(arg, "--zygote") == 0) {zygote = true;niceName = ZYGOTE_NICE_NAME;} else if (strcmp(arg, "--start-system-server") == 0) {startSystemServer = true;} else if (strcmp(arg, "--application") == 0) {application = true;} else if (strncmp(arg, "--nice-name=", 12) == 0) {niceName.setTo(arg + 12);} else if (strncmp(arg, "--", 2) != 0) {className.setTo(arg);break;} else {--i;break;}}Vector<String8> args;if (!className.isEmpty()) {//...} else {// We're in zygote mode.maybeCreateDalvikCache();if (startSystemServer) {args.add(String8("start-system-server"));}char prop[PROP_VALUE_MAX];if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",ABI_LIST_PROPERTY);return 11;}String8 abiFlag("--abi-list=");abiFlag.append(prop);args.add(abiFlag);// In zygote mode, pass all remaining arguments to the zygote// main() method.for (; i < argc; ++i) {args.add(String8(argv[i]));}}if (!niceName.isEmpty()) {runtime.setArgv0(niceName.string());set_process_name(niceName.string());}if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);} else {fprintf(stderr, "Error: no class name or --zygote supplied.\n");app_usage();LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");return 10;}
}
复制代码

AndroidRuntime.start

该函数的主要工作:

  1. 调用startVm函数启动DVM虚拟机
  2. 调用java层的ZygoteInit.main函数
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{ALOGD(">>>>>> START %s uid %d <<<<<<\n",className != NULL ? className : "(unknown)", getuid());static const String8 startSystemServer("start-system-server");//...//启动虚拟机JniInvocation jni_invocation;jni_invocation.Init(NULL);JNIEnv* env;if (startVm(&mJavaVM, &env, zygote) != 0) {return;}onVmCreated(env);//...s/** Start VM.  This thread becomes the main thread of the VM, and will* not return until the VM exits.*/char* slashClassName = toSlashClassName(className);jclass startClass = env->FindClass(slashClassName);if (startClass == NULL) {ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);/* keep going */} else {//调用ZygoteInit.main函数jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");if (startMeth == NULL) {ALOGE("JavaVM unable to find main() in '%s'\n", className);/* keep going */} else {env->CallStaticVoidMethod(startClass, startMeth, strArray);#if 0if (env->ExceptionCheck())threadExitUncaughtException(env);
#endif}}free(slashClassName);ALOGD("Shutting down VM\n");if (mJavaVM->DetachCurrentThread() != JNI_OK)ALOGW("Warning: unable to detach main thread\n");if (mJavaVM->DestroyJavaVM() != 0)ALOGW("Warning: VM did not shut down cleanly\n");
}复制代码

ZygoteInit

main

main函数主要的任务是

  1. 通过registerZygoteSocket创建一个ServerSocket由于后续进程间通信
  2. 调用preload函数,预加载一些通用类(这些类定义在./frameworks/base/preloaded-classes文件中)、通用资源(如Drawaelb等,这些资源定义在./frameworks/base/core/res/res/values/arrays.xml中)、共享库等等。
  3. 调用startSystemServer启动SystemServer进程
  4. 调用runSelectLoop函数进入死循环,不停地检测是否有Socket通信
public static void main(String argv[]) {try {//...boolean startSystemServer = false;String socketName = "zygote";String abiList = null;//...//创建一个ServerSocketregisterZygoteSocket(socketName);//...//预先加载class、资源、共享库等等preload();//...//启动SystemServerif (startSystemServer) {startSystemServer(abiList, socketName);}runSelectLoop(abiList);closeServerSocket();} catch (MethodAndArgsCaller caller) {caller.run();} catch (RuntimeException ex) {Log.e(TAG, "Zygote died with exception", ex);closeServerSocket();throw ex;}
}static void preload() {Log.d(TAG, "begin preload");preloadClasses();preloadResources();preloadOpenGL();preloadSharedLibraries();preloadTextResources();// Ask the WebViewFactory to do any initialization that must run in the zygote process,// for memory sharing purposes.WebViewFactory.prepareWebViewInZygote();Log.d(TAG, "end preload");
}private static void registerZygoteSocket(String socketName) {if (sServerSocket == null) {int fileDesc;final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;try {String env = System.getenv(fullSocketName);fileDesc = Integer.parseInt(env);} catch (RuntimeException ex) {throw new RuntimeException(fullSocketName + " unset or invalid", ex);}try {FileDescriptor fd = new FileDescriptor();fd.setInt$(fileDesc);sServerSocket = new LocalServerSocket(fd);} catch (IOException ex) {throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex);}}
}private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();fds.add(sServerSocket.getFileDescriptor());peers.add(null);while (true) {StructPollfd[] pollFds = new StructPollfd[fds.size()];for (int i = 0; i < pollFds.length; ++i) {pollFds[i] = new StructPollfd();pollFds[i].fd = fds.get(i);pollFds[i].events = (short) POLLIN;}try {Os.poll(pollFds, -1);} catch (ErrnoException ex) {throw new RuntimeException("poll failed", ex);}for (int i = pollFds.length - 1; i >= 0; --i) {if ((pollFds[i].revents & POLLIN) == 0) {continue;}if (i == 0) {ZygoteConnection newPeer = acceptCommandPeer(abiList);peers.add(newPeer);fds.add(newPeer.getFileDesciptor());} else {boolean done = peers.get(i).runOnce();if (done) {peers.remove(i);fds.remove(i);}}}}
}复制代码

总结

经过上面对于zygote进程启动流程的分析,我们可以总结出zygote进程启动过程中究竟做了什么事情

  1. 启动DVM虚拟机
  2. 预加载部分资源,如一些通用类、通用资源、共享库等
  3. 启动system_server进程
  4. 创建一个ServerSocket,并进入死循环监听Socket消息。

Zygote进程启动流程分析相关推荐

  1. Android系统的心脏-Zygote进程启动流程分析

    简介: Android中,Zygote是整个Android系统的核心进程,是Android系统的心脏.所有的Android应用程序,包括Android框架层所在的进程system_server,都是由 ...

  2. 【Android】系统启动流程(zygote 进程启动流程)

    前言 先上图,大致了解一下 Android 设备点击电源键开机到创建出 system_server 进程的流程, 里面细化的子流程和 system_server 之后发生的事情我将会在后续的文章中详细 ...

  3. Android 9 (P) Zygote进程启动源码分析指南二

         Android 9 Zygote进程启动源码分析指南二 Android 9 (P) 系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 Andro ...

  4. Android系统启动流程—— init进程zygote进程SystemServer进程启动流程

    原文地址:https://blog.csdn.net/qq_30993595/article/details/82714409 Android系统启动流程 Android系统启动过程往细了说可以分为5 ...

  5. 从源码解析-Android系统启动流程概述 init进程zygote进程SystemServer进程启动流程

    Android系统启动流程 启动流程 Loader Kernel Native Framework Application init进程 启动 rc文件规则 Actions Commands Serv ...

  6. Zygote进程启动过程源代码分析

    Zygote进程介绍 在Android系统中,存在不同的服务,这些服务可以分为: Android系统借用Binder通信机制实现了C/S架构设计,客户端应用程序如需要实现某些功能,只需请求指定的服务, ...

  7. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

  8. Android 系统(12)---Zygote进程启动过程

    android系统进程启动流程 android系统的Zygote进程是所有android进程的父进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的.Zygote(孵 ...

  9. Launcher进程启动流程

    Launcher进程启动流程 在分析ActivityManagerService启动流程的时候说过,ActivityManagerService启动完成后,会调用ActivityTaskManager ...

最新文章

  1. 使用chrome下载m3u8视频
  2. linux下的各种系统错误errno描述一览
  3. 医学计算机应用第五版题库,医科医学计算机应用题库
  4. 前端学习(1651):前端系列实战课程之json和字符串互转
  5. 微型计算机中最小的单位,微型计算机中最小的数据单位是
  6. java restful开发规范_restful api 开发规范
  7. enscape材质名称大全_2020年茅台价格表和图片大全一览 茅台酒真假鉴别方法
  8. java.util —— 工具类
  9. XmlSerializer对象
  10. win7信息服务器,Windos2012 中的共享,win8/win10用户访问正常,WIN7用户不能访问
  11. Vue2.0安装教程
  12. 遗传算法详解(GA)(个人觉得很形象,很适合初学者)
  13. 洛谷在线测试P1878_舞蹈课
  14. 我国超级计算机的发展成就,中国最近的科技发展成就
  15. 从《人民的名义》看声纹识别技术在案件侦查中的应用
  16. 如何有效提升技术[成为大Niu]的两个方法
  17. 晨枫U盘维护工具V2.0版(转)
  18. plc to和from命令
  19. 连载|线性判别分析(LDA)
  20. linux uvc 拍照程序,Linux uvc摄像头驱动初探

热门文章

  1. NSA释出逆向工程工具GHIDRA针对恶意软件逆向分析
  2. Linux/Unix shell 监控Oracle告警日志(monitor alter log file)
  3. Java动态代理与Cglib代理
  4. AOS V1.0 发布,JavaEE 应用基础平台
  5. 库函数strlen源码重现及注意问题
  6. 虚拟机中LINUX系统的安装
  7. JOOMLA中文安装时 数据库发生错误解块办法
  8. C#三种判断字符是否为汉字的方法
  9. 每天一个linux命令(18):locate 命令
  10. J2EE业务层模式:服务门面,应用服务,以及业务委托,服务定位器