android启动过程分析——zygote进程

概要

  • 从字面上看,zygote是“受精卵”的意思。zygote是android系统应用中一个相当重要的进程,它的主要功能是执行android应用程序。在android系统中运行新的应用,如同受精分裂一样,需要跟zygote进程(拥有应用程序运行时所需要的各种元素与条件)结合后才能执行。

  • zygote进程运行时,会初始化Dalvik虚拟机,并启动它。android的应用程序是由Java编写的,它们不能直接以本地进程的形态运行在Linux上,只能运行在Dalvik虚拟机中。并且,每个应用程序都运行在各自的虚拟机中,应用程序每次运行都要重新初始化并启动虚拟机,这个过程会耗费相当长时间,是拖慢应用程序的原因之一。因此,在android中,应用程序运行前,zygote进程通过共享已运行的虚拟机的代码和内存信息,缩短应用程序运行所耗费的时间。并且,它会事先将应用程序要使用的android framework中的类和资源加载到内存中,并组织所使用资源的链接信息,这就会节省大量时间,提高程序运行速度。

  • 在android系统中有以下两种进程:

    • Java应用程序,主要基于ART虚拟机,所有的应用程序apk都属于这类。
    • native程序,也就是使用C和C++语言开发的 程序,比如bootanimation。

    所有的Java应用程序进程以及系统服务SystemServer进程都是由zygote进程通过Linux的fork()函数孵化出来,而native进程则由init进程创建启动。zygote进程最初的名字是app_process,但是zygote进程在启动的过程中,通过Linux下的pctrl系统调用换成了zygote。

  • zygote是一个C/S模型,zygote进程作为服务端,其他进程作为一个客户端向它发出“孵化”请求,而zygote接收这个请求之后就会“孵化”出一个新的进程。如下图,当Launcher里的应用程序图标去启动一个新的应用程序进程时,这个请求会到达框架层的核心服务ActivityManagerService中,当ActivityManagerService收到这个请求之后,会通过调用Process类发送一个“孵化”子进程的Socket请求,而zygote监听到了这个请求之后就会立刻fork一个新的进程出来。

    zygote孵化框架

zygote进程的启动

  • zygote本身是一个native的应用程序,它被init进程启动起来,在init.rc文件中的配置如下:

    service zygote /system/bin/app_process64 -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

    第一行代码的意思是,这个native service的名字为zygote,它的可执行程序是 /system/bin/app_process64。

    第二行的关键字class为main,表示service的类型是main。

    第三行的关键字socket,表示zygote进程会创建一个名称为zygote的socket,通过adb可以在/dev/socket目录下看到这个名为zygote的文件。这里定义的socket的类型是UNIX domain Socket,用作进程间通信,当启动一个新的应用程序时,系统框架中服务ActivityManagerService会调用Process类,Process类通过这个socket来和zygote进程通信,请求zygote进程fork一个应用程序。

    最后几行关键字onrestart,表示这个zygote进程重启时需要执行的命令。

  • zygote进程对应的主文件为app_main.cpp,当它被init进程启动起来之后,就会进入主文件app_main.cpp的main()函数。

    int main(int argc, char* const argv[])
    {

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
    if (errno != EINVAL) {
    LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
    return 12;
    }
    }
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    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]));
    }
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;
    ++i;
    while (i < argc) {
    const char* arg = argv[i++];
    if (strcmp(arg, "--zygote") == 0) {
    zygote = true;
    niceName = ZYGOTE_NICE_NAME; // ZYGOTE_NICE_NAME就是“zygote”,此处已换名字
    } else if (strcmp(arg, "--start-system-server") == 0) {
    startSystemServer = true; // 在init.rc里配置了前面这些参数,而zygote进程在启动的时候,init进程会传过来这些参数,所以此处把startSystemServer设置为true,代表SystemServer。
    } 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()) {
    args.add(application ? String8("application") : String8("tool"));
    runtime.setClassNameAndArgs(className, argc - i, argv + i);
    } else {
    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);
    for (; i < argc; ++i) {
    args.add(String8(argv[i]));
    }
    }
    if (!niceName.isEmpty()) {
    runtime.setArgv0(niceName.string());
    // 此处调用set_process_name()函数,通过Linux下的pctrl系统调用把名字“app_process”换成了“zygote”
    set_process_name(niceName.string());
    }
    if (zygote) {
    // zygote为true代表的是zygote进程,也就是谁现在正在启动zygote进程。因为zygote进程是通过自己的资源复制一份来fork一个新的子进程的,也就是说子进程也会进入这个文件的main函数,所以通过这个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;
    }

    }

    可以看到main()函数最后会调用runtime的start()函数,runtime是一个AppRuntime对象,AppRuntime类继承AndroidRuntime的start()函数。

    void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
    {

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
    className != NULL ? className : "(unknown)", getuid());
    static const String8 startSystemServer("start-system-server");
    for (size_t i = 0; i < options.size(); ++i) {
    if (options[i] == startSystemServer) {
    const int LOG_BOOT_PROGRESS_START = 3000;
    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    }
    }
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
    rootDir = "/system";
    if (!hasDir("/system")) {
    LOG_FATAL("No root directory specified, and /android does not exist.");
    return;
    }
    setenv("ANDROID_ROOT", rootDir, 1);
    }
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    // 启动虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
    return;
    }
    onVmCreated(env);
    // 注册JNI函数
    if (startReg(env) < 0) {
    ALOGE("Unable to register all android natives\n");
    return;
    }
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    for (size_t i = 0; i < options.size(); ++i) {
    jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
    assert(optionsStr != NULL);
    env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
    ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    } else {
    // 调用类的main方法
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
    "([Ljava/lang/String;)V");
    if (startMeth == NULL) {
    ALOGE("JavaVM unable to find main() in '%s'\n", className);
    } else {
    // 调用ZygoteInit的main函数
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
    #if 0
    if (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");

    }

    可以看到,AndroidRuntime的start()函数主要做了以下三件事情。

    • 调用startVM()函数启动虚拟机

      int AndroidRuntime::startVm(JavaVM pJavaVM, JNIEnv pEnv, bool zygote){

      1
      2
      3
      4
      5
      6
      7
      .......
      // 主要通过JNI_CreateJavaVM()创建虚拟机
      if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
      ALOGE("JNI_CreateJavaVM failed\n");
      return -1;
      }
      return 0;

      }

    • 调用startReg()函数注册JNI方法

      int AndroidRuntime::startReg(JNIEnv* env){

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      ATRACE_NAME("RegisterAndroidNatives");
      androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
      ALOGV("--- registering native functions ---\n");
      env->PushLocalFrame(200);
      // startReg()函数通过register_jni_procs()函数去进一步注册,并且传递的值是gRegJNI变量,gRegJNI是一个数组。在android中,Java世界要调用native世界的函数就要用JNI机制,并且android系统中也大量使用JNI机制,register_jni_procs通过这个数组来完成Java到native方法的映射。
      if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
      env->PopLocalFrame(NULL);
      return -1;
      }
      env->PopLocalFrame(NULL);
      return 0;

      }

    • 调用ZygoteInit类的main函数

      public static void main(String argv[]){

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      ZygoteHooks.startZygoteNoThreadCreation();
      try {
      Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
      RuntimeInit.enableDdms();
      SamplingProfilerIntegration.start();
      boolean startSystemServer = false;
      String socketName = "zygote";
      String abiList = null;
      for (int i = 1; i < argv.length; i++) {
      if ("start-system-server".equals(argv[i])) {
      startSystemServer = true;
      } else if (argv[i].startsWith(ABI_LIST_ARG)) {
      abiList = argv[i].substring(ABI_LIST_ARG.length());
      } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
      socketName = argv[i].substring(SOCKET_NAME_ARG.length());
      } else {
      throw new RuntimeException("Unknown command line argument: " + argv[i]);
      }
      }
      if (abiList == null) {
      throw new RuntimeException("No ABI list supplied.");
      }
      registerZygoteSocket(socketName);
      Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
      SystemClock.uptimeMillis());
      preload();
      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
      SystemClock.uptimeMillis());
      Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
      SamplingProfilerIntegration.writeZygoteSnapshot();
      Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
      gcAndFinalize();
      Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
      Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
      Trace.setTracingEnabled(false);
      Zygote.nativeUnmountStorageOnInit();
      ZygoteHooks.stopZygoteNoThreadCreation();
      if (startSystemServer) {
      startSystemServer(abiList, socketName);
      }
      Log.i(TAG, "Accepting command socket connections");
      runSelectLoop(abiList);
      closeServerSocket();
      } catch (MethodAndArgsCaller caller) {
      caller.run();
      } catch (RuntimeException ex) {
      Log.e(TAG, "Zygote died with exception", ex);
      closeServerSocket();
      throw ex;
      }

      }

      ZygoteInit类的main()方法主要做了以下5项工作:

      • 调用registerZygoteSocket()函数创建一个zygote的socket接口,用来和AMS通信

        ​ private static void registerZygoteSocket(String socketName) {

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        if (sServerSocket == null) {
        // 使用文件描述符作为参数,通过new关键字创建了一个Java层的LocalServerSocket对象,目的是等待创建新的应用程序进程请求连接,而这个文件描述符代表的就是前面说的/dev/socket/zygote,即在init.rc中zygote service配置的内容
        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);
        }
        }

        ​ }

      • 调用preload()预加载类和资源

        static void preload() {

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        Log.d(TAG, "begin preload");
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "BeginIcuCachePinning");
        beginIcuCachePinning();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
        // 加载类
        preloadClasses();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
        // 加载资源
        preloadResources();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
        // 加载OpenGL
        preloadOpenGL();
        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
        // 加载共享库(预加载"android","compiler_rt", "jnigraphics"这几个库);
        preloadSharedLibraries();
        preloadTextResources();
        WebViewFactory.prepareWebViewInZygote();
        endIcuCachePinning();
        warmUpJcaProviders();
        Log.d(TAG, "end preload");

        }

      • 调用startSystemServer()函数来启动SystemServer进程

      • 调用runSelectLoop()函数在前面创建的socket接口上进入一个无限循环,等待核心服务AMS请求创建新的应用程序进程

        private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
```c++
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) {
// 如果变量i==0,表示zygote socket服务还没有准备好,于是接下来就回去准备它,这个过程是zygote进程在启动时去做的
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
// 如果变量i!=0,表示正在等待客户端来连接“Zygote”这个socket,当有孵化子进程的请求时,就会调用ZygoteConnection的runOnce()函数创建新的子进程
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}

  • 调用caller.run()方法,当启动一个新进程,会抛出MethodAndArgsCaller异常,当捕获了这个异常之后,就调用MethodAndArgsCaller类的run方法
  • 综上可以通过一张图来小结一下zygote启动的大概过程

    zygote启动过程序列图

启动system_server进程

  • 首先,回顾一下android framework的启动过程

    android framework启动过程

    zygote启动虚拟机后,会再生成一个虚拟机实例,以便运行名称为SystemServer的Java服务,SystemServer用于运行Audio Flinger与Surface Flinger本地服务。在运行完所需的本地服务后,SystemServer开始运行android framework的服务,如AMS、WMS、PMS等。

  • 启动系统服务system_server进程从ZygoteInit.java的main()方法调用startSystemServer()方法开始。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
}
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
// 首先设置syytem_server进程的uid、gid和groups,然后设置进程的名字为--nice-name=system_server
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
// forkSystemServer()函数用来fork一个新的进程,它有两个返回值,一个在当前进程中返回,另一个在新创建的进程中返回,在当前进程中的返回值就是新创建的子进程的pid,而新创建进程中的返回值是0。所以,如果pid=0,表示已经进入SystemServer子进程。
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// 在system_server子进程中调用handleSystemServerProcess()方法用来关闭“Zygote”socket。
handleSystemServerProcess(parsedArgs);
}
return true;
}

接着看handleSystemServerProcess()方法实现

private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)

​ throws ZygoteInit.MethodAndArgsCaller {

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// handleSystemServerProcess首先会关闭socket,因为system_server进程继承了zygote进程,所以也继承了socket,但由于system_server不需要这个socket,所以必须close它。
closeServerSocket();
Os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
}
if (parsedArgs.invokeWith != null) {
String[] args = parsedArgs.remainingArgs;
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
}
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createSystemServerClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

}

handleSystemServerProcess()函数在最后调用了RuntimeInit.zygoteInit()方法,zygoteInit()主要调用了nativeZygoteInit()和applicationInit()这两个方法。

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

​ throws ZygoteInit.MethodAndArgsCaller {

1
2
3
4
5
6
7
8
9
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
redirectLogStreams();
commonInit();
// 主要执行了Binder驱动程序初始化的相关工作,它调用之后system_server进程就可以进行Binder进程间通信
nativeZygoteInit();
// 主要是进入SystemServer.java的main()方法
applicationInit(targetSdkVersion, argv, classLoader);

nativeZygoteInit()是一个native的方法,对应于jni下的AndroidRuntime.cpp文件里的com_android_internal_os_RuntimeInit_nativeZygoteInit()函数。

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) {

1
2
// gCurRuntime是一个全局变量,指向AppRuntime,因此,这里实际调用的是AppRuntime的onZygoteInit()函数
gCurRuntime->onZygoteInit();

}

visual void onZygoteInit() {

1
2
3
4
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
// 变量proc是一个ProcessState对象,这里调用它的函数startThreadPool来启动线程池,用来进行进程间通信
proc->startThreadPool();

}

回到前面再继续看看applicationInit()方法怎样一步步进入SystemServer的main()方法。

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)

​ throws ZygoteInit.MethodAndArgsCaller {

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
return;
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// 该方法调用之后就会进入类的main()方法
invokeStaticMain(args.startClass, args.startArgs, classLoader);

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)

​ throws ZygoteInit.MethodAndArgsCaller {

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Class<?> cl;
try {
// 通过Class.forName把类加载进来,在目前情况下,这个类就是前面传过来的SystemServer类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
// 通过cl.getMethod获取加载类的静态main()方法,即获取SystemServer类的main()方法
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
// 最后并没有直接调用SystemServer类的main()方法,而是通过关键字throw抛出一个异常对象ZygoteInit.MethodAndArgsCaller,从前面的分析可以知道,这个异常对象在ZygoteInit的main()函数中被捕获,当捕获这个异常之后就会调用SystemServer类的main()方法,之所以通过抛出异常来进入加载类的main()方法,目的是清理堆栈,这样做会让加载SystemServer类的main()方法觉得自己是进程的入口类
throw new ZygoteInit.MethodAndArgsCaller(m, argv);

启动app应用程序进程

前面分析了zygote如何启动SystemServer子进程,接下类再分析zygote如何启动其他子进程,也就是创建应用程序进程的过程,这个过程和创建SystemServer进程基本一样。

  • 当点击Launcher主界面的一个应用程序图标时,如果这个应用程序还未曾启动,就会启动它。而判断应用程序有没有启动都由核心服务ActivityManagerService来做,它的startProcessLocked()方法会真正地启动应用程序子进程。

    private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    long startTime = SystemClock.elapsedRealtime();
    if (app.pid > 0 && app.pid != MY_PID) {
    checkTime(startTime, "startProcess: removing from pids map");
    synchronized (mPidsSelfLocked) {
    mPidsSelfLocked.remove(app.pid);
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
    }
    checkTime(startTime, "startProcess: done removing from pids map");
    app.setPid(0);
    }
    if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
    "startProcessLocked removing on hold: " + app);
    mProcessesOnHold.remove(app);
    checkTime(startTime, "startProcess: starting to update cpu stats");
    updateCpuStats();
    checkTime(startTime, "startProcess: done updating cpu stats");
    try {
    try {
    final int userId = UserHandle.getUserId(app.uid);
    AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
    } catch (RemoteException e) {
    throw e.rethrowAsRuntimeException();
    }
    int uid = app.uid;
    int[] gids = null;
    int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
    if (!app.isolated) {
    int[] permGids = null;
    try {
    checkTime(startTime, "startProcess: getting gids from package manager");
    final IPackageManager pm = AppGlobals.getPackageManager();
    permGids = pm.getPackageGids(app.info.packageName,
    MATCH_DEBUG_TRIAGED_MISSING, app.userId);
    MountServiceInternal mountServiceInternal = LocalServices.getService(
    MountServiceInternal.class);
    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
    app.info.packageName);
    } catch (RemoteException e) {
    throw e.rethrowAsRuntimeException();
    }
    if (ArrayUtils.isEmpty(permGids)) {
    gids = new int[2];
    } else {
    gids = new int[permGids.length + 2];
    System.arraycopy(permGids, 0, gids, 2, permGids.length);
    }
    gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
    gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
    }
    checkTime(startTime, "startProcess: building args");
    if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
    && mTopComponent != null
    && app.processName.equals(mTopComponent.getPackageName())) {
    uid = 0;
    }
    if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
    && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
    uid = 0;
    }
    }
    int debugFlags = 0;
    if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
    debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
    debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
    }
    if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
    mSafeMode == true) {
    debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
    }
    if ("1".equals(SystemProperties.get("debug.checkjni"))) {
    debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
    }
    String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
    if ("true".equals(genDebugInfoProperty)) {
    debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
    }
    if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
    debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
    }
    if ("1".equals(SystemProperties.get("debug.assert"))) {
    debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
    }
    if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
    debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
    debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
    debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
    mNativeDebuggingApp = null;
    }
    String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
    if (requiredAbi == null) {
    requiredAbi = Build.SUPPORTED_ABIS[0];
    }
    String instructionSet = null;
    if (app.info.primaryCpuAbi != null) {
    instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
    }
    app.gids = gids;
    app.requiredAbi = requiredAbi;
    app.instructionSet = instructionSet;
    boolean isActivityProcess = (entryPoint == null);
    if (entryPoint == null) entryPoint = "android.app.ActivityThread";
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
    app.processName);
    checkTime(startTime, "startProcess: asking zygote to start proc");
    // AMS的startProcessLocked()方法调用了Process类的start()方法为应用程序创建新的进程,这里的参数entryPoint为"android.app.ActivityThread",它是传进去的第一个参数,也就是应用程序初始化进程时要加载的主文件Java类。当应用程序启动之后,会把这个类加载到进程,调用它的main()方法作为应用程序进程的入口。
    Process.ProcessStartResult startResult = Process.start(entryPoint,
    app.processName, uid, uid, gids, debugFlags, mountExternal,
    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
    app.info.dataDir, entryPointArgs);
    checkTime(startTime, "startProcess: returned from zygote!");
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    if (app.isolated) {
    mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
    }
    mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
    checkTime(startTime, "startProcess: done updating battery stats");
    EventLog.writeEvent(EventLogTags.AM_PROC_START,
    UserHandle.getUserId(uid), startResult.pid, uid,
    app.processName, hostingType,
    hostingNameStr != null ? hostingNameStr : "");
    try {
    AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
    app.info.seinfo, app.info.sourceDir, startResult.pid);
    } catch (RemoteException ex) {
    }
    if (app.persistent) {
    Watchdog.getInstance().processStarted(app.processName, startResult.pid);
    }
    checkTime(startTime, "startProcess: building log message");
    StringBuilder buf = mStringBuilder;
    buf.setLength(0);
    buf.append("Start proc ");
    buf.append(startResult.pid);
    buf.append(':');
    buf.append(app.processName);
    buf.append('/');
    UserHandle.formatUid(buf, uid);
    if (!isActivityProcess) {
    buf.append(" [");
    buf.append(entryPoint);
    buf.append("]");
    }
    buf.append(" for ");
    buf.append(hostingType);
    if (hostingNameStr != null) {
    buf.append(" ");
    buf.append(hostingNameStr);
    }
    Slog.i(TAG, buf.toString());
    app.setPid(startResult.pid);
    app.usingWrapper = startResult.usingWrapper;
    app.removed = false;
    app.killed = false;
    app.killedByAm = false;
    checkTime(startTime, "startProcess: starting to update pids map");
    synchronized (mPidsSelfLocked) {
    this.mPidsSelfLocked.put(startResult.pid, app);
    if (isActivityProcess) {
    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
    msg.obj = app;
    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
    ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
    }
    }
    checkTime(startTime, "startProcess: done updating pids map");
    } catch (RuntimeException e) {
    Slog.e(TAG, "Failure starting process " + app.processName, e);
    forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
    }

    }

    接下来看看Process的start()方法。

    public static final ProcessStartResult start(final String processClass,

    final String niceName,

    int uid, int gid, int[] gids,

    int debugFlags, int mountExternal,

    int targetSdkVersion,

    String seInfo,

    String abi,
    String instructionSet,
    String appDataDir,
    String[] zygoteArgs) {

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try {
    return startViaZygote(processClass, niceName, uid, gid, gids,
    debugFlags, mountExternal, targetSdkVersion, seInfo,
    abi, instructionSet, appDataDir, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
    Log.e(LOG_TAG,
    "Starting VM process through Zygote failed");
    throw new RuntimeException(
    "Starting VM process through Zygote failed", ex);
    }

    }

    Process类的start()方法就是简单地调用startViaZygote()方法来进一步操作。

    public static ProcessStartResult startViaZygote(final String processClass,

    final String niceName,

    final int uid, final int gid,

    final int[] gids,

    int debugFlags, int mountExternal,

    int targetSdkVersion,

    String seInfo,

    String abi,
    String instructionSet,
    String appDataDir,
    String[] extraArgs)

    throws ZygoteStartFailedEx {

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList<String>();
// 设置参数值,这些值是应用程序在安装时系统分配好的
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
argsForZygote.add("--enable-jni-logging");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
argsForZygote.add("--enable-safemode");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
argsForZygote.add("--enable-debugger");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
argsForZygote.add("--enable-checkjni");
}
if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
argsForZygote.add("--generate-debug-info");
}
if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {
argsForZygote.add("--always-jit");
}
if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {
argsForZygote.add("--native-debuggable");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
argsForZygote.add("--enable-assert");
}
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
argsForZygote.add("--mount-external-read");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
argsForZygote.add("--mount-external-write");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
if (gids != null && gids.length > 0) {
StringBuilder sb = new StringBuilder();
sb.append("--setgroups=");
int sz = gids.length;
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(',');
}
sb.append(gids[i]);
}
argsForZygote.add(sb.toString());
}
if (niceName != null) {
argsForZygote.add("--nice-name=" + niceName);
}
if (seInfo != null) {
argsForZygote.add("--seinfo=" + seInfo);
}
if (instructionSet != null) {
argsForZygote.add("--instruction-set=" + instructionSet);
}
if (appDataDir != null) {
argsForZygote.add("--app-data-dir=" + appDataDir);
}
argsForZygote.add(processClass);
if (extraArgs != null) {
for (String arg : extraArgs) {
argsForZygote.add(arg);
}
}
// 调用openZygoteSocketIfNeeded()方法链接“zygote”socket,主要是通过ZygoteState的connect()方法去链接“zygote”socket。zygoteSendArgsAndGetResult()方法通过socket写入流writer把前面传过来的那些参数写进去,socket即ZygoteInit类的runSelectLoop()函数监听。写入这些数据后,ZygoteInit类的runSelectLoop()函数就能被监听到。
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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 {
// 当监听到runSelectLoop()函数之后,就会调用peers.get(i).runOnce()方法做进一步处理
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
Log.w(TAG, "IOException on command socket " + ex.getMessage());
closeSocket();
return true;
}
if (args == null) {
closeSocket();
return true;
}
PrintStream newStderr = null;
if (descriptors != null && descriptors.length >= 3) {
newStderr = new PrintStream(
new FileOutputStream(descriptors[2]));
}
int pid = -1;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
try {
parsedArgs = new Arguments(args);
if (parsedArgs.abiListQuery) {
return handleAbiListQuery();
}
if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
throw new ZygoteSecurityException("Client may not specify capabilities: " +
"permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
}
applyUidSecurityPolicy(parsedArgs, peer);
applyInvokeWithSecurityPolicy(parsedArgs, peer);
applyDebuggerSystemProperty(parsedArgs);
applyInvokeWithSystemProperty(parsedArgs);
int[][] rlimits = null;
if (parsedArgs.rlimits != null) {
rlimits = parsedArgs.rlimits.toArray(intArray2d);
}
if (parsedArgs.invokeWith != null) {
FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
childPipeFd = pipeFds[1];
serverPipeFd = pipeFds[0];
Os.fcntlInt(childPipeFd, F_SETFD, 0);
}
int [] fdsToClose = { -1, -1 };
FileDescriptor fd = mSocket.getFileDescriptor();
if (fd != null) {
fdsToClose[0] = fd.getInt$();
}
fd = ZygoteInit.getServerSocketFileDescriptor();
if (fd != null) {
fdsToClose[1] = fd.getInt$();
}
fd = null;
// 之前启动SystemServer进程的代码与此有点相似。此处是通过Zygote.forkAndSpecialize()来fork新的应用程序进程,而启动system_server进程时是通过Zygote.forkSystemServer()来fork SystemServer进程。
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
} catch (ErrnoException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (IllegalArgumentException ex) {
logAndPrintError(newStderr, "Invalid zygote arguments", ex);
} catch (ZygoteSecurityException ex) {
logAndPrintError(newStderr,
"Zygote security policy prevents request: ", ex);
}
try {
if (pid == 0) {
// 在子进程中,这里通过handleChildProc()方法能做进一步处理,而之前是通过调用handleSystemServerProc()来处理
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
closeSocket();
ZygoteInit.closeServerSocket();
if (descriptors != null) {
try {
Os.dup2(descriptors[0], STDIN_FILENO);
Os.dup2(descriptors[1], STDOUT_FILENO);
Os.dup2(descriptors[2], STDERR_FILENO);
for (FileDescriptor fd: descriptors) {
IoUtils.closeQuietly(fd);
}
newStderr = System.err;
} catch (ErrnoException ex) {
Log.e(TAG, "Error reopening stdio", ex);
}
}
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
} else {
// handleChildProc()方法调用了RuntimeInit类的zygoteInit()方法来做进一步处理,后面的启动过程跟前面启动SystemServer的过程基本一样,唯一不同的是SystemServer进程启动之后进入的主类是SystemServer.java,而应用程序进程启动起来之后进入的主类是ActivityThread.java,但最终都会进入main()方法。
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}

小结

至此,zygote进程以及zygote进程启动SystemServer进程和启动应用程序进程就分析完了。zygote进程为了启动SystemServer进程和启动应用程序进程主要做了两件事:

  • 初始化Binder驱动用来进行进程间通信
  • 通过反射进入main()方法

zygote进程是android应用运行必须的进程,zygote进程如何运行、如何初始化,以及如何通过它来提高应用的运行速度等,是需要讨论的主要内容。在android平台下,zygote进程有助于快速运行应用程序,可以高效地向android平台添加资源,快速加载相关类,在运行新的应用程序的过程中减小系统开销。