前言

init进程启动后,最重要的一个进程就是Zygote进程,Zygote是所有应用的鼻祖。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。
Zygote进程由app_process启动,Zygote是一个C/S模型,Zygote进程作为服务端,其他进程作为客户端向它发出“孵化-fork”请求,而Zygote接收到这个请求后就“孵化-fork”出一个新的进程。
由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个Java虚拟机的实例拷贝。
架构图

Zygote是如何启动的

init进程启动后,会解析init.rc文件,然后创建和加载service字段指定的进程。zygote进程就是以这种方式,被init进程加载的。
system/core/rootdir/init.rc

import /system/etc/init/hw/init.${ro.zygote}.rc

其中${ro.zygote} 由各个厂家使用,现在的主流厂家基本使用zygote64_32,因此,我们的rc文件为 init.zygote64_32.r。它会启动两个zygote进程(名为zygote和zygote——secondary),对应的执行程序分别是app_prcocess64(主模式)、app_process32。
init.zygote64_32.rc
system/core/rootdir/init.zygote64_32.rc

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    priority -20
    user root //用户为root
    group root readproc reserved_disk //访问组支持root readproc reserved_disk
    socket zygote stream 660 root system //创建一个socket,名字叫zygote,以tcp形式,可以在/dev/socket 中看到一个 zygote的socket
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
     onrestart restart audioserver
     onrestart restart cameraserver
     onrestart restart media
     onrestart restart netd
     onrestart restart wificond
     task_profiles ProcessCapacityHigh MaxPerformance
     critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
 
 service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
     class main
     priority -20
     user root
     group root readproc reserved_disk
     socket zygote_secondary stream 660 root system
     socket usap_pool_secondary stream 660 root system
     onrestart restart zygote
     task_profiles ProcessCapacityHigh MaxPerformance

从上面一段代码可以看出:
第一个Zygote进程:
进程名:zygote
进程通过 /system/bin/app_process64来启动
启动参数: -Xzygote
/system/bin
–zygote
–start-system-server
–socket-name=zygote
socket的名称:zygote
第二个Zygote进程:
进程名:zygote_secondary
进程通过 /system/bin/app_process32来启动
启动参数: -Xzygote
/system/bin
–zygote
–socket-name=zygote_secondary
–enable-lazy-preload
socket的名称:zygote_secondary
对应的代码入口为:frameworks/base/cmds/app_process/app_main.cpp

Zygote启动后做了什么

init进程通过init.zygote64_32.rc来调用/system/bin/app_process64 来启动zygote进程,入口app_main.cpp
frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
    /* 
zygote传入的参数是:
        -Xzygote
        /system/bin
        --zygote
        --start-system-server
        --socket-name=zygote
    
zygote_secondary传入的参数是:
        -Xzygote
        /system/bin
        --zygote
        --socket-name=zygote_secondary
        --enable-lazy-preload  
    */
    
    ......
 
    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;
 
    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            //对于64位系统nice_name为zygote64,32位系统为zygote
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            //是否需要启动system server
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            //启动进入独立的程序模式
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            //niceName为当前进程别名,区别abi型号
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }
 
    Vector<String8> args;
    if (!className.isEmpty()) {//className不为空,说明是application启动模式
        // We're not in zygote mode, the only argument we need to pass
        // to RuntimeInit is the application argument.
        //
        // The Remainder of args get passed to startup class main(). Make
        // copies of them before we overwrite them with the process name.
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);
 
        if (!LOG_NDEBUG) {
          String8 restOfArgs;
          char* const* argv_new = argv + i;
          int argc_new = argc - i;
          for (int k = 0; k < argc_new; ++k) {
            restOfArgs.append("\"");
            restOfArgs.append(argv_new[k]);
            restOfArgs.append("\" ");
          }
          ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
        }
    } else {
        // We're in zygote mode.
        //进入zygote模式
        //新建Dalvik的缓存目录:/data/dalvik-cache
        maybeCreateDalvikCache();
 
        if (startSystemServer) {
            //添加start-system-server参数
            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);
        //添加--abi-list=参数
        args.add(abiFlag);
 
        // In zygote mode, pass all remaining arguments to the zygote
        // main() method.
        for (; i < argc; ++i) {
            //将剩下的参数加入args
            args.add(String8(argv[i]));
        }
    }
    
    //设置一个“好听的昵称” zygote\zygote64,之前的名称是app_process
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }
 
    if (zygote) {
        //如果是zygote启动模式,则加载ZygoteInit
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        //如果是application启动模式,则加载RuntimeInit
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        //没有指定类名或zygote,参数错误
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

Zygote本身是一个Native的应用程序,刚开始的进程名称为“app_process”,运行过程中,通过调用setArgv0将名字改为zygote 或者 zygote64(根据操作系统而来),最后通过runtime的start()方法来真正的加载虚拟机并进入JAVA世界。
在app_main.cpp的最后调用了runtime.start()方法,runtime是AppRuntime的对象,AppRuntime是AndroidRuntime的子类,
进入到AndroidRuntime.cpp#start()
frameworks/base/core/jni/AndroidRuntime.cpp

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");
    // Whether this is the primary zygote, meaning the zygote which will fork system server.
    bool primary_zygote = false;
 
    ......
        
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
 
    //启动虚拟机,主要是关于虚拟机参数的设置
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);//空函数,没有任何实现
 
    /*
     * Register android functions.
     */
    //注册JNI方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
 
    /*
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
 
    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    //等价 strArray[0] = "com.android.internal.os.ZygoteInit"
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
 
    //strArray[1]="start-system-server";
    //strArray[2]="--abi-list=xxx";
    //其中xxx为系统响应的cpu架构类型,比如arm64-v8a
    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);
    }
 
    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    //将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit"
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);//找到Zygoteinit
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        //找到这个类后,继续找成员函数main方法的Method ID
        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 {
            //通过反射调用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");
}

在start()方法中主要完成了:

  1. 调用startVm开启虚拟机,主要是配置虚拟机的相关参数
  2. 调用startReg注册JNI方法
  3. 使用JNI把Zyogte进程启动

在start()方法的最后用来反射调用了ZygoteInit的main函数,Zygote便进入了Java框架层。
进入到ZygoteInit.java#main()
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String[] argv) {
    //1.创建ZygoteServer
   ZygoteServer zygoteServer = null;
 
   // Mark zygote start. This ensures that thread creation will throw
   // an error.
    //调用native函数,确保当前没有其它线程在运行
   ZygoteHooks.startZygoteNoThreadCreation();
 
   // Zygote goes into its own process group.
    //设置pid为0,Zygote进入自己的进程组
   try {
       Os.setpgid(0, 0);
   } catch (ErrnoException ex) {
       throw new RuntimeException("Failed to setpgid(0,0)", ex);
   }
 
   Runnable caller;
   try {
       // Store now for StatsLogging later.
       final long startTime = SystemClock.elapsedRealtime();
       final boolean isRuntimeRestarted = "1".equals(
               SystemProperties.get("sys.boot_completed"));
 
        //得到systrace的监控TAG
       String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
       TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
               Trace.TRACE_TAG_DALVIK);
       //通过systrace来追踪函数ZygoteInit,可以通过systrace工具来进行分析
       //traceBegin和traceEnd要成对出现,而且需要使用同一个tag
       bootTimingsTraceLog.traceBegin("ZygoteInit");
       //开启DDMS(Dalvik Debug Monitor Service)功能
       //注册所有已知的Java VM的处理块的监听器。线程监听、内存监听、native 堆内存监听、debug模式监听等等
       RuntimeInit.preForkInit();
 
       boolean startSystemServer = false;
       String zygoteSocketName = "zygote";
       String abiList = null;
       boolean enableLazyPreload = false;
 
       //2.解析app_main.cpp#start()传入的参数
       for (int i = 1; i < argv.length; i++) {
           if ("start-system-server".equals(argv[i])) {
               startSystemServer = true;//启动zygote时,才会传入参数:start-system-server
           } else if ("--enable-lazy-preload".equals(argv[i])) {
               enableLazyPreload = true;//启动zygote_secondary时,才会传入参数:enable-lazy-preload
           } else if (argv[i].startsWith(ABI_LIST_ARG)) {
               abiList = argv[i].substring(ABI_LIST_ARG.length());//通过属性ro.product.cpu.abilist64\ro.product.cpu.abilist32 从C空间传来的值
           } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
               zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());//会有两种值:zygote和zygote_secondary
           } else {
               throw new RuntimeException("Unknown command line argument: " + argv[i]);
           }
       }
 
       //根据传入socket name来决定是创建zygote还是zygote_secondary
       final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
    
       if (!isRuntimeRestarted) {
           if (isPrimaryZygote) {
               FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                       BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START,
                       startTime);
           } else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) {
               FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                       BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START,
                       startTime);
           }
       }
 
       if (abiList == null) {
           throw new RuntimeException("No ABI list supplied.");
       }
 
       // In some configurations, we avoid preloading resources and classes eagerly.
       // In such cases, we will preload things prior to our first fork.
       // 在第一次zygote启动时,enableLazyPreload为false,执行preload
       if (!enableLazyPreload) {
           //systrace 追踪 ZygotePreload
           bootTimingsTraceLog.traceBegin("ZygotePreload");
           EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                   SystemClock.uptimeMillis());
           /// M: Added for BOOTPROF
           addBootEvent("Zygote:Preload Start");
           /// @}
           // 3.加载进程的资源和类
           preload(bootTimingsTraceLog);
           EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                   SystemClock.uptimeMillis());
           //systrace结束 ZygotePreload的追踪
           bootTimingsTraceLog.traceEnd(); // ZygotePreload
       }
 
        // Do an initial gc to clean up after startup
        bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
        gcAndFinalize();
        bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
       
        //结束ZygoteInit的systrace追踪
        bootTimingsTraceLog.traceEnd(); // ZygoteInit
 
        Zygote.initNativeState(isPrimaryZygote);
 
        /// M: Added for BOOTPROF
        addBootEvent("Zygote:Preload End");
        /// @}
        ZygoteHooks.stopZygoteNoThreadCreation();
 
        // 4.调用ZygoteServer 构造函数,创建socket,会根据传入的参数
        // 创建两个socket:/dev/socket/zygote 和 /dev/socket/zygote_secondary
        zygoteServer = new ZygoteServer(isPrimaryZygote);
 
        if (startSystemServer) {
            //5.fork出SystemServer
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
 
            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
            // child (system_server) process.
            //启动SystemServer
            if (r != null) {
                r.run();
                return;
            }
        }
 
        Log.i(TAG, "Accepting command socket connections");
 
        // The select loop returns early in the child process after a fork and
        // loops forever in the zygote.
        //6.zygote进程进入无限循环,处理请求
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with fatal exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }
 
    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
    if (caller != null) {
        caller.run();
    }
}

总结zygoteInit.java#main()完成了:

  1. 创建ZygoteServer
  2. 解析了从app_main.cpp#start()传入的参数
  3. 加载进程的资源和类
  4. 调用ZygoteServer构造函数,创建sokect
  5. fork出SystemServer
  6. zygote进程进入无限循环,处理请求

进入到ZygoteInit.java#preload()预加载

预加载是指在zygote进程启动的时候就加载,这样系统只在zygote执行一次加载操作,所有APP用到该资源不需要再重新加载,减少资源加载时间,加快了应用启动速度,一般情况下,系统中App共享的资源会被列为预加载资源。
zygote fork子进程时,根据fork的copy-on-write(写时拷贝)机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
预加载的原理:
zygote进程启动后将资源读取出来,保存到Resources一个全局静态变量中,下次读取系统资源的时候优先从静态变量中查找。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

static void preload(TimingsTraceLog bootTimingsTraceLog) {
    Log.d(TAG, "begin preload");
    bootTimingsTraceLog.traceBegin("BeginPreload");
    beginPreload();//获取字符集转换资源等
    bootTimingsTraceLog.traceEnd(); // BeginPreload
    bootTimingsTraceLog.traceBegin("PreloadClasses");
    //预加载类的列表---/system/etc/preloaded-classes, 在/frameworks/base/config/preloaded-classes 中,Android10.0中预计有7603左右个类
    preloadClasses();
    bootTimingsTraceLog.traceEnd(); // PreloadClasses
    bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
    cacheNonBootClasspathClassLoaders();
    bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
    bootTimingsTraceLog.traceBegin("PreloadResources");
    //加载图片、颜色等资源文件,部分定义在 /frameworks/base/core/res/res/values/arrays.xml中
    preloadResources();
    bootTimingsTraceLog.traceEnd(); // PreloadResources
    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
    nativePreloadAppProcessHALs();
    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
    Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");
    maybePreloadGraphicsDriver();
    Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
    // 加载 android、compiler_rt、jnigraphics等library
    preloadSharedLibraries();
    //用于初始化文字资源
    preloadTextResources();
    // Ask the WebViewFactory to do any initialization that must run in the zygote process,
    // for memory sharing purposes.
    //用于初始化webview;
    WebViewFactory.prepareWebViewInZygote();
    //预加载完成,可以查看下面的log
    endPreload();
    warmUpJcaProviders();
    Log.d(TAG, "end preload");
 
    sPreloadComplete = true;
}

进入到ZygoteServer.java#ZygoteServer(boolean isPrimaryZygote)
说明:ZygoteServer 构造函数初始化时,根据传入的参数,利用LocalServerSocket (createManagedSocketFromInitSocket()方法中调用)创建了1个本地服务端的socket,用来建立连接。
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

//创建zygote的socket
ZygoteServer(boolean isPrimaryZygote) {
    mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
 
    if (isPrimaryZygote) {
        //创建socket,并获取socket对象,socketname:zygote
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
        mUsapPoolSocket =
                Zygote.createManagedSocketFromInitSocket(
                        Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
    } else {
        //socketname:zygote_secondary
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
        mUsapPoolSocket =
                Zygote.createManagedSocketFromInitSocket(
                        Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
    }
 
    mUsapPoolSupported = true;
    fetchUsapPoolPolicyProps();
}

进入到ZygoteInit.java#forkSystemServer()
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    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_PTRACE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG,
            OsConstants.CAP_WAKE_ALARM,
            OsConstants.CAP_BLOCK_SUSPEND
    );
    ....
    //准备参数
    /* Hardcoded command line to start the system server */
    String[] args = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                    + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs;
 
    int pid;
 
    try {
        ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
        try {
            //将上面准备的参数,按照ZygoteArguments的风格进行封装
            parsedArgs = ZygoteArguments.getInstance(commandBuffer);
        } catch (EOFException e) {
            throw new AssertionError("Unexpected argument error for forking system server", e);
        }
        commandBuffer.close();
        Zygote.applyDebuggerSystemProperty(parsedArgs);
        Zygote.applyInvokeWithSystemProperty(parsedArgs);
 
    .....
        //通过fork“分裂”出子进程system_server
        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
 
    //进入子进程system_server
    /* For child process */
    if (pid == 0) {
        // 处理32_64和64_32的情况
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        // fork时会copy socket,system server需要主动关闭
        zygoteServer.closeServerSocket();
        // system server进程处理自己的工作
        return handleSystemServerProcess(parsedArgs);
    }
 
    return null;
}

主要时调用了Zygote.java#forkSystemServer()方法,在这个方法中调用了Native的方法,但最后会调用fork()方法创建子进程。
fork()函数得到的子进程是父进程的一个复制品,通过写时拷贝实现。
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次。
返回值:

  • 返回0:表示成功创建子进程,并且接下来进入子进程执行liuc
  • 返回>0:表示成功创建子进程,并且急促执行父进程流程代码
  • 返回非正数<0:表示创建子进程失败,失败的原因主要有:进程数超过了系统所能创建的上线,errno会被设置为EAGAIN系统内存不足,errno会被设置为ENOMEM

回到ZygoteServer()方法中,在新fork出的子进程中调用了handleSystemServerProcess(),主要是返回Runtime.java的MethodAndArgsCaller的方法,然后通过r.run() 启动com.android.server.SystemServer的main 方法。
这个当我们后面的SystemServer的章节进行详细讲解。
handleSystemServerProcess代码流程:

handleSystemServerProcess()
    |
    [ZygoteInit.java]
    zygoteInit()
        |
    [RuntimeInit.java]
    applicationInit()
        |
    findStaticMain()
        |
    MethodAndArgsCaller()

进入ZygoteServer.java#runSelectLoop()
说明:使zygote进程进入无限循环,处理请求
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

Runnable runSelectLoop(String abiList) {
    ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
    ArrayList<ZygoteConnection> peers = new ArrayList<>();
 
    //将server socket加入到fds
    socketFDs.add(mZygoteSocket.getFileDescriptor());
    peers.add(null);
 
    mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
 
    while (true) {
        fetchUsapPoolPolicyPropsWithMinInterval();
        mUsapPoolRefillAction = UsapPoolRefillAction.NONE;
 
        int[] usapPipeFDs = null;
        StructPollfd[] pollFDs;
        //每次循环,都重新创建需要监听的pollFds
        if (mUsapPoolEnabled) {
            usapPipeFDs = Zygote.getUsapPipeFDs();
            pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
        } else {
            pollFDs = new StructPollfd[socketFDs.size()];
        }
 
        int pollIndex = 0;
        for (FileDescriptor socketFD : socketFDs) {
            //关注事件到来
            pollFDs[pollIndex] = new StructPollfd();
            pollFDs[pollIndex].fd = socketFD;
            pollFDs[pollIndex].events = (short) POLLIN;
            ++pollIndex;
        }
 
        final int usapPoolEventFDIndex = pollIndex;
 
        if (mUsapPoolEnabled) {
            pollFDs[pollIndex] = new StructPollfd();
            pollFDs[pollIndex].fd = mUsapPoolEventFD;
            pollFDs[pollIndex].events = (short) POLLIN;
            ++pollIndex;
 
            // The usapPipeFDs array will always be filled in if the USAP Pool is enabled.
            assert usapPipeFDs != null;
            for (int usapPipeFD : usapPipeFDs) {
                FileDescriptor managedFd = new FileDescriptor();
                managedFd.setInt$(usapPipeFD);
 
                pollFDs[pollIndex] = new StructPollfd();
                pollFDs[pollIndex].fd = managedFd;
                pollFDs[pollIndex].events = (short) POLLIN;
                ++pollIndex;
            }
        }
 
        int pollTimeoutMs;
 
        if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) {
            pollTimeoutMs = -1;
        } else {
            long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp;
 
            if (elapsedTimeMs >= mUsapPoolRefillDelayMs) {
                // The refill delay has elapsed during the period between poll invocations.
                // We will now check for any currently ready file descriptors before refilling
                // the USAP pool.
                pollTimeoutMs = 0;
                mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
                mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;
 
            } else if (elapsedTimeMs <= 0) {
                // This can occur if the clock used by currentTimeMillis is reset, which is
                // possible because it is not guaranteed to be monotonic.  Because we can't tell
                // how far back the clock was set the best way to recover is to simply re-start
                // the respawn delay countdown.
                pollTimeoutMs = mUsapPoolRefillDelayMs;
 
            } else {
                pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs);
            }
        }
 
        int pollReturnValue;
        try {
            //等待事件到来
            pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
 
        if (pollReturnValue == 0) {
            // The poll returned zero results either when the timeout value has been exceeded
            // or when a non-blocking poll is issued and no FDs are ready.  In either case it
            // is time to refill the pool.  This will result in a duplicate assignment when
            // the non-blocking poll returns zero results, but it avoids an additional
            // conditional in the else branch.
            mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
            mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;
 
        } else {
            boolean usapPoolFDRead = false;
            //倒序处理,即优先处理已建立链接的信息,后处理新建链接的请求
            while (--pollIndex >= 0) {
                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                    continue;
                }
 
                //server socket最先加入fds,因此这里是server socket收到数据
                if (pollIndex == 0) {
                    // Zygote server socket
                    //收到新的建立通信的请求,建立通信连接
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    //加入到peers和fds,即下一次也开监听
                    peers.add(newPeer);
                    socketFDs.add(newPeer.getFileDescriptor());
                } else if (pollIndex < usapPoolEventFDIndex) {
                    // Session socket accepted from the Zygote server socket
                    //说明接收AMS发送过来创建应用程序的请求,调用processOneCommand来创建新的应用程序进程
                    try {
                        //有socket连接,创建ZygoteConnection对象,并添加到fds
                        ZygoteConnection connection = peers.get(pollIndex);
                        boolean multipleForksOK = !isUsapPoolEnabled()
                                && ZygoteHooks.isIndefiniteThreadSuspensionSafe();
                        //处理连接
                        final Runnable command =
                                connection.processCommand(this, multipleForksOK);
 
                        // TODO (chriswailes): Is this extra check necessary?
                        if (mIsForkChild) {
                            // We're in the child. We should always have a command to run at
                            // this stage if processCommand hasn't called "exec".
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            }
 
                            return command;
                        } else {
                            // We're in the server - we should never have any commands to run.
                            if (command != null) {
                                throw new IllegalStateException("command != null");
                            }
 
                            // We don't know whether the remote side of the socket was closed or
                            // not until we attempt to read from it from processCommand. This
                            // shows up as a regular POLLIN event in our regular processing
                            // loop.
                            if (connection.isClosedByPeer()) {
                                connection.closeSocket();
                                peers.remove(pollIndex);
                                socketFDs.remove(pollIndex);//处理完则从fds中移除该文件描述符
                            }
                        }
                    } catch (Exception e) {
                        ......
                    } finally {
                        // Reset the child flag, in the event that the child process is a child-
                        // zygote. The flag will not be consulted this loop pass after the
                        // Runnable is returned.
                        mIsForkChild = false;
                    }
 
                }
                    ......
}

processOneCommand()
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
.....
            if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
                    || !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
                // Continue using old code for now. TODO: Handle these cases in the other path.
                //fork子进程
                pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,
                        parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits,
                        parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName,
                        fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                        parsedArgs.mInstructionSet, parsedArgs.mAppDataDir,
                        parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList,
                        parsedArgs.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,
                        parsedArgs.mBindMountAppStorageDirs);
 
                try {
                    if (pid == 0) {
                        // in child
                        //子进程执行
                        zygoteServer.setForkChild();
    
                        zygoteServer.closeServerSocket();
                        IoUtils.closeQuietly(serverPipeFd);
                        serverPipeFd = null;
                        //进入子进程流程
                        return handleChildProc(parsedArgs, childPipeFd,
                                parsedArgs.mStartChildZygote);
                    } else {
                        // In the parent. A pid < 0 indicates a failure and will be handled in
                        // handleParentProc.
                        //父进程执行
                        IoUtils.closeQuietly(childPipeFd);
                        childPipeFd = null;
                        handleParentProc(pid, serverPipeFd);
                        return null;
                    }
                }
        .....
}

handleChildProc()
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

private Runnable handleChildProc(ZygoteArguments parsedArgs,
        FileDescriptor pipeFd, boolean isZygote) {
 
    closeSocket();
 
    Zygote.setAppProcessName(parsedArgs, TAG);
 
    // End of the postFork event.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    if (parsedArgs.mInvokeWith != null) {
        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                VMRuntime.getCurrentInstructionSet(),
                pipeFd, parsedArgs.mRemainingArgs);
 
        // Should not get here.
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        if (!isZygote) {
            //App进程将会调用到这里,执行目标类的main()方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(
                    parsedArgs.mRemainingArgs  /* classLoader */);
        }
    }
}

总结

  1. 开启虚拟器
  2. 注册了JNI
  3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层
  4. 创建了服务端Socket
  5. 预加载类和资源
  6. 启动SystemServer进程
  7. 通过runSelectLoop函数无限循环等待如AMS等的请求
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐