Zygote 进程启动流程分析一

362 阅读3分钟

什么是 zygote 进程

我们知道 Android 系统中用户空间的第一个进程是 init, 而 init 进程的部分工作就是创建 zygote 进程。 在 Android 系统中,所有应用程序的进程以及系统服务进程 SystemServer 都是由 zygote 进程来完成的。所以 Zygote 也被称之为受精卵进程,因为它完成了很多孵化操作,由此可见 zygote 在 Android 系统中的地位非同一般。

init.rc

Android 系统启动后会创建 init 进程,它的目录在 system/core/init/init.cpp 在这里会进行启动属性服务(propert)以及解析 init.rc 文件,init.rc 是 Android 系统配置的配置文件,其文件目录为 system/core/rootdir/init.rc , 在 init.rc 文件中第12行 import /init.${ro.zygote}.rc 引入了zygote.rc。查看同目录下的 init.zygote32.rc 代码如下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main # 指的是 zygote 的 class name 为 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

其中第一行解释如下: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

  • service: 启动一个服务
  • zygote: 进程名称
  • /system/bin/app_process: 二进制执行文件路径
  • -Xzygote /system/bin --zygote --start-system-server: 传递的参数

Service 命名会促使 init 进程调用 fork 函数来创建一个新的进程,这里 Service 通知 init 进程创建一个名为 zygote 的进程,而这个进程的可执行程序路径为 syste/bin/app_process, 后面则是执行 app_process 时需要传递的参数。

app_process 是一个可执行程序,我们需要进一步查找 app_process 的源码存放路径,我们知道在 Framework 中二进制文件需要经过 make 编译来生成,而 make 的目标文件 Android.mk/bp 中 可以定义 app_process, 我们通过 grep app_process ./ -rn 就能查找到 app_processframeworks/base/cmds/app_process/Android.mk 中有定义, 这样我们就找到了 app_process 的源码存放路径。

zogote 的执行程序源码是 frameworks/base/cmds/app_process/ , 在 main 函数中会调用 runtime.start 来启动 zygote

int main(int argc, char* const argv[])
{
……
runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
……
}

这里的 runtime 其实就是 AppRuntime,而 AppRuntime 继承至 AndroidRuntime,main 方法中的 start 函数执行的就是 AndroidRuntime 中的 start

framewords/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const char* options)
{
    ……
   JNIEnv* env;
    if (startVm(&mJavaVM, &env) != 0) {//启动虚拟机
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {//在虚拟机中注册function
        ALOGE("Unable to register all android natives\n");
        return;
    }
    /*
     * 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);//找到ZygoteInit类
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");//调用静态main方法
    }
}

Zygote 进程在启动的时候会创建 JVM,因此通过 fork 创建的应用程序和 SystemServer 进程可以在内部获取一个 JavaVM 的实例。在启动 Zygote 的时候传过来的类为 com.android.internal.os.ZygoteInit , 在这里通过反射的方式条用其 main 函数进一步完成启动初始化的过程。

// 在AndroidRuntime 的 start 方法通过反射调用的
public static void main(String argv[]) {
   try {
       // Start profiling the zygote initialization.
       SamplingProfilerIntegration.start();
				
     	 // 注册zygote本地Socket服务 监听来自AMS的创建应用进程请求
       registerZygoteSocket();
       EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
           SystemClock.uptimeMillis());
     	 // 预加载 一些资源,类等
       preload();
       
     	 ……
       
       // "start-system-server" 是上面 runtime.start 传递的参数
       if (argv[1].equals("start-system-server")) {
           // 启动SystemServer进程
           startSystemServer();
       } else if (!argv[1].equals("")) {
           throw new RuntimeException(argv[0] + USAGE_STRING);
       }

       Log.i(TAG, "Accepting command socket connections");
			 
       // 等待客户端消息
       runSelectLoop();
				
       closeServerSocket();
   } catch (MethodAndArgsCaller caller) {
       caller.run();
   } catch (RuntimeException ex) {
       Log.e(TAG, "Zygote died with exception", ex);
       closeServerSocket();
       throw ex;
   }
}

到这一步我们可以看到在 Zygote 的初始化中, 主要做了以下几件事情:

  • 通过 registerZygoteSocke 创建 Zygote 的 Socket 服务,它是一个 LocalSocketServer , 用来等待 ActivityMangerServer 请求 Zygote 创建应用进程的请求。
  • 监听 Socket 服务器,等待 ActivityManagerServer 创建的应用进程的请求。
  • 创建 SystemServer 进程。