Android 进阶——系统启动之Android进程造物者Zygote 进程启动详解

Posted CrazyMo_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 进阶——系统启动之Android进程造物者Zygote 进程启动详解相关的知识,希望对你有一定的参考价值。

引言

前面系列文章介绍了android系统的第一个用户进程——init进程由解析init.rc脚本启动,完成属性系统的初始化等工作后紧接着启动Android系统上的造物者——Zygote进程,这篇文章接着分析。

写时拷贝(Copy On Write):Linux 进程基本上都是通过fork 创建的,fork出来的子进程除了内核中一些核心数据结构和父进程不同之外,其余大部分的内存空间都是和父进程共享的,当且仅当子进程需要去改写这些共享内存时,内核才会为子进程分配一个新的页面,并将老页面的数据复制一份到新页面中。

以后更多精选系列文章以高度完整的系列形式发布在公众号,真正的形成一套完整的技术栈,欢迎关注,目前第一个系列是关于Android系统启动系列的文章,大概有二十几篇干货:

一、Zygote进程概述

Zygote 中文翻译受精卵,是由Android系统第一个用户进程init进程启动起来的,在Android 系统中,所有的应用程序进程包括用于运行系统关键核心服务的SystemServer进程都是由Zygote 进程fork 而来的,就像受精卵一样具有孵化的功能,因此又被它称之为进程孵化器。即Zygote 通过 fork自身(复制自身)方式创建System进程和应用程序进程的。而且Zygote 进程在启动时会自主在内部创建一个VM实例,而通过fork 而得到的所有子进程自然继承Zygote的空间,换言之,System进程和应用进程内部也持有一个VM实例的拷贝,这样进程才可以通过这个VM实例运行Java 语言开发的程序组件

fork 函数执行成功后,会有两次返回,其中一次是在当前进程中返回,另一次是在新创建出来的子进程中返回(当返回值等于0时)。

二、Zygote进程的启动

1、Init进程解析init.rc脚本触发Zygote进程的启动

1.1、init.rc 脚本触发zygote 以service 形式启动

Zygote进程是通过aosp/system/core/rootdir/init.rc脚本启动的,如下所示部分内容

import /init.environ.rc
import /init.usb.rc
import /init.$ro.hardware.rc
import /init.usb.configfs.rc
import /init.$ro.zygote.rc
....

在第五行init.$ro.zygote.rc可以看到有一个全局系统属性名为ro.zygote(我设备得到的值zygote64_32)

adb shell getprop | grep ro.zygote

其实这是一个init.rc 的动态引入的语法,则代表引入的.rc文件名为 init.zygote64_32.rc,内容如下:

service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks

service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
    class main
    socket zygote_secondary stream 660 root system
    onrestart restart zygote
    writepid /dev/cpuset/foreground/tasks

由上得知,定义了两个Zygote服务:zygote和zygote_secondary,分别对应不同的可执行文件,前者是app_process32,后者是app_process64。但它们进程的可执行文件都是app_process,对应的源码在/frameworks/base/cmds/app_process/app_main.cpp。

1.2、解析 init.zygote64_32.rc 中的service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote 指令

当解析到第一行的命令时,遇到service 指令时就会相应地调用system/core/init/service.cpp # Service::start函数来执行启动工作,对应的含义依次为zygote进程所对应的应用程序文件为/system/bin/app_process32,就紧接着跟着进程启动需要传递的参数,--start-system-server 表示Zygote进程启动完毕后需要马上将System进程启动。对应的app_process 启动命令格式:

app_process [虚拟机参数]  运行目录  参数 [Java类]
名称说明
虚拟机参数以“-”开头,用于指定指定Android虚拟机时的参数
运行目录程序的运行目录,一般是/system/bin
参数以“–”开头,比如–zygote 表示要启动的zygote进程,–application则表示以普通进程的方式执行Java代码
Java类要执行的Java类,即执行这个类的静态方法main,需要注意传递参数“–zygote” 时不会执行这个类而是执行ZygoteInit这个类的main方法

1.3、调用system/core/init/service.cpp # Service::start 函数创建zygote进程和/system/core/init/util.cpp # create_socket函数创建名为zygote 的socket

bool Service::Start() 
   ...
    pid_t pid = fork();
    if (pid == 0) 
        umask(077);

        for (const auto& ei : envvars_) 
            add_environment(ei.name.c_str(), ei.value.c_str());
        
		//遍历为Zygote进程配置的socket列表,并创建对应的socket并把返回的fd发布到系统中
        for (const auto& si : sockets_) 
            int socket_type = ((si.type == "stream" ? SOCK_STREAM :
                                (si.type == "dgram" ? SOCK_DGRAM :
                                 SOCK_SEQPACKET)));
            const char* socketcon =
                !si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str();

            int s = create_socket(si.name.c_str(), socket_type, si.perm,
                                  si.uid, si.gid, socketcon);
            if (s >= 0) 
                PublishSocket(si.name, s);
            
        
		...
        std::vector<std::string> expanded_args;
        std::vector<char*> strs;
        expanded_args.resize(args_.size());
        strs.push_back(const_cast<char*>(args_[0].c_str()));
        for (std::size_t i = 1; i < args_.size(); ++i) 
            if (!expand_props(args_[i], &expanded_args[i])) 
                ERROR("%s: cannot expand '%s'/n", args_[0].c_str(), args_[i].c_str());
                _exit(127);
            
            strs.push_back(const_cast<char*>(expanded_args[i].c_str()));
        
        strs.push_back(nullptr);
		//str[0] 值等于/system/bin/app_process 通过shell 加载该文件
        if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) 
            ERROR("cannot execve('%s'): %s/n", strs[0], strerror(errno));
        

        _exit(127);
    

    if (pid < 0) 
        ERROR("failed to start '%s'/n", name_.c_str());
        pid_ = 0;
        return false;
    
    ...
    return true;

第二行就表示在Zygote启动过程中需要再内部创建一个名为“zygote”的socket,用于执行与System 进程进行通信的。

/*
 * create_socket - creates a Unix domain socket in ANDROID_SOCKET_DIR
 * ("/dev/socket") as dictated in init.rc. This socket is inherited by the
 * daemon. We communicate the file descriptor's value via the environment
 * variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo").
 */
int create_socket(const char *name, int type, mode_t perm, uid_t uid,
                  gid_t gid, const char *socketcon)

    struct sockaddr_un addr;
    int fd, ret, savederrno;
    char *filecon;

    if (socketcon) 
        if (setsockcreatecon(socketcon) == -1) 
            ERROR("setsockcreatecon(/"%s/") failed: %s/n", socketcon, strerror(errno));
            return -1;
        
    
	//调用内核的socket函数创建并返回对应的fd,PF_UNIX表示创建用于本地进程间通信的类型socket,比如说AMS 在请求与Zygote进程通信时创建新的应用进程前,需要先打开下面绑定的设备文件来创建一个连接到Zygote 进程的客户端socket
    fd = socket(PF_UNIX, type, 0);
    if (fd < 0) 
        ERROR("Failed to open socket '%s': %s/n", name, strerror(errno));
        return -1;
    

    if (socketcon)
        setsockcreatecon(NULL);

    memset(&addr, 0 , sizeof(addr));
    addr.sun_family = AF_UNIX;
    //ANDROID_SOCKET_DIR 是一个宏 值为/dev/socket
    snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s",
             name);

    ret = unlink(addr.sun_path);
    if (ret != 0 && errno != ENOENT) 
        ERROR("Failed to unlink old socket '%s': %s/n", name, strerror(errno));
        goto out_close;
    

    filecon = NULL;
    if (sehandle) 
        ret = selabel_lookup(sehandle, &filecon, addr.sun_path, S_IFSOCK);
        if (ret == 0)
            setfscreatecon(filecon);
    
	//bind 函数的作用就是将上面创建socket的返回的fd 与socket地址addr 绑定起来得到一个设备文件——dev/socket/zygote
    ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr));
    savederrno = errno;

    setfscreatecon(NULL);
    freecon(filecon);

    if (ret) 
        ERROR("Failed to bind socket '%s': %s/n", name, strerror(savederrno));
        goto out_unlink;
    
	//配置权限
    ret = lchown(addr.sun_path, uid, gid);
    if (ret) 
        ERROR("Failed to lchown socket '%s': %s/n", addr.sun_path, strerror(errno));
        goto out_unlink;
    
    ret = fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW);
    if (ret) 
        ERROR("Failed to fchmodat socket '%s': %s/n", addr.sun_path, strerror(errno));
        goto out_unlink;
    

    INFO("Created socket '%s' with mode '%o', user '%d', group '%d'/n",
         addr.sun_path, perm, uid, gid);

    return fd;

out_unlink:
    unlink(addr.sun_path);
out_close:
    close(fd);
    return -1;

socket 创建完毕之后还需要通过/system/core/init/service.cpp#PublishSocket 函数发布到系统中

void Service::PublishSocket(const std::string& name, int fd) const 
    std::string key = StringPrintf(ANDROID_SOCKET_ENV_PREFIX "%s", name.c_str());
    std::string val = StringPrintf("%d", fd);
    add_environment(key.c_str(), val.c_str());

    /* make sure we don't close-on-exec */
    fcntl(fd, F_SETFD, 0);

2、Zygote进程加载system/bin/app_process文件完成启动

从上面我们可以知道Zygote进程在启动过程中会加载system/bin/app_process程序文件,app_process 除了能启动Zygote进程,还可以使用它来执行Java类中的某个main方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zo0nLkyn-1638888067002)(assets/image-20210715154633309.png)]

2.1、执行/frameworks/base/cmds/app_process/app_main.cpp # main 函数

app_process/app_main.cpp的main函数主要作用就是解析传入的启动参数,完成以下工作。

2.1.1、创建AppRuntime 对象

在app_main.cpp文件里定义了AppRuntime 类(AppRuntime继承自AndroidRuntime类),主要用于创建和初始化虚拟机以及启动Java线程,AppRuntime 在一个进程中有且只有一个实例对象并保存在全局变量gCurRuntime指针中

\\frameworks\\base\\core\\jni\\AndroidRuntime.cpp

AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
        mExitWithoutCleanup(false),
        mArgBlockStart(argBlockStart),
        mArgBlockLength(argBlockLength)

    SkGraphics::Init();//初始化skia 图形引擎
    // Pre-allocate enough space to hold a fair number of options. 预分配空间来存放传入的虚拟机参数
    mOptions.setCapacity(20);

    assert(gCurRuntime == NULL);        // one per process 确保只能被初始化一次
    gCurRuntime = this;

2.1.2、给AppRuntime 配置参数和设置进程名称(即将当前进程名称设置为zygote)

2.1.3、解析启动参数

解析参数后niceName的值为zygote,startSystemServer的值为true,zygote为true。

2.1.4、AppRuntime #start函数执行ZygoteInit或者RuntimeInit类的main方法

如果启动的不是zygote进程则执行RuntimeInit类

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

    ...
     //创建runtime局部对象,Zygote 进程就是需要依靠它来继续完成启动的,如果启动的是Zygote进程那么ZygoteInit类中会进入等到Socket事件的循环,不会被销毁;而执行的是一个java类则会在执行完毕后被销毁。
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    argc--;
    argv++;
    // 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;
            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);
        
        ...
    

    Vector<String8> args;
    if (!className.isEmpty()) 
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);
     else 
        // We're in zygote mode.
        maybeCreateDalvikCache();
        if (startSystemServer) 
            args.add(String8("start-system-server"));
        
        String8 abiFlag("--abi-list=");
        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);
    
    ...

2.2、frameworks/base/core/jni/AndroidRuntime.cpp # start

Zygote进程在运行Java代码前还需要初始化整个Java运行环境。

2.2.1、设置环境变量ANDROID_ROOT的值为/system

2.2.2、进行JNI 接口初始化并启动虚拟机并触发onVmCreated 函数回调

实际上是触发AppRuntime#onVmCreated 回调。

2.2.3、startReg注册系统JNI函数

通过调用register_jni_procs函数将全局数组gRegJNI的本地JNI函数注册到虚拟机中。

2.2.4、JNI调用 com.android.internal.os.ZygoteInit的main函数

/*
 * Start the Android runtime.  This involves starting the virtual machine
 * and calling the "static void main(String[] args)" method in the class
 * named by "className".
 *
 * Passes the main function two arguments, the class name and the specified
 * options string.
 */
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)

    //标志着Android系统启动,因为以后的应用进程都是由zygotefork出来的,所以不会再执行start函数了,如果系统反复出现这个日志且id都是zygote则说明Zygote进程在不断地被重启。
     ALOGD(">>>>>> START %s uid %d <<<<<<\\n",className != NULL ? className : "(unknown)", getuid());
    //定义变量直接初始化,其字面值是"start-system-server"的副本(不包括最后的那个空字符)
    static const String8 startSystemServer("start-system-server");
    /*
     * 'startSystemServer == true' means runtime is obsolete and not run from
     * init.rc anymore, so we print out the boot start event here.
     */
    for (size_t i = 0; i < options.size(); ++i) 
        if (options[i] == startSystemServer) 
           /* track our progress through the boot sequence */
           const int LOG_BOOT_PROGRESS_START = 3000;
        
    
    //环境变量ANDROID_ROOT的设置,即环境变量ANDROID_ROOT的值被设置成了/system
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) 
        rootDir = "/system";
        if (!hasDir("/system")) 
            return;
        
        setenv("ANDROID_ROOT", rootDir, 1);
    

    /* start the virtual machine */
    //通过jni_invocation.Init(NULL)完成jni接口的初始化,并启动虚拟机的代码,后续再分析细节
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) 
        return;
    
    onVmCreated(env);

    /*
     * Register android functions.注册系统JNI函数
     */
    if (startReg(env) < 0) 
        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 = 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);
    

    /*
     * 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 
        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 
            //jni调用传入的className 即 com.android.internal.os.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");

2.3、JNI调用/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java #main 方法

    public static void main(String argv[]) 
    	 ...
        boolean isFirstBooting = false;
        ZygoteHooks.startZygoteNoThreadCreation();
        try 
            boolean startSystemServer = false;
            String socketName = "zygote";
            	...
            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]);
                
            
            registerZygoteSocket(socketName);
            if(!isFirstBooting && !isBox)
                if (startSystemServer) 
                    startSystemServer(abiList, socketName);
                
            
             preload();
            ...
            runSelectLoop(abiList);
            closeServerSocket();
         catch (MethodAndArgsCaller caller) 
            caller.run();
         catch (Throwable ex) 
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        
    

2.3.1、registerZygoteSocket(socketName) 创建一个Server端socket用于等待AMS 请求Zygote进程创建新的应用进程

    private static void registerZygoteSocket(String socketName) 
        if (sServerSocket == null) 
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try 
                //通过系统环境变量得到fd的值并转换为fd
                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);
            
        
    

2.3.2、调用preload方法预加载系统资源

包括系统预加载类、Framework资源和OpenGL资源,当应用被fork创建出来后,应用进程内自然就包含了这些资源,无需应用再次自己加载。

2.3.3、startSystemServer(abiList, socketName) fork 创建System进程(SystemServer进程)

    /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException 

        /* Hardcoded command line to start the system server */
        //System进程启动的参数,可以看到System进程的用户ID和用户组ID都是1000,同时还有其他用户组的权限
        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 
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            //fork 创建System进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
         catch (IllegalArgumentException ex) 
            throw new RuntimeException(ex);
        

        /* For child process */
        if (pid == 0) 
            if (hasSecondZygote(abiList)) 
                if(isBox)
                    waitForSecondaryZygote(socketName);
                
                Log.d(TAG,"--------call waitForSecondaryZygote,skip this---,abiList= "+abiList);
            
            // 处理System进程启动事宜
            handleSystemServerProcess(parsedArgs);
        

        return true;
    

2.3.4、执行runSelectLoop(abiList) 方法等待处理AMS 请求Zygote 创建新应用进程

    /**
     * Runs the zygote process's select loop. Accepts new connections as
     * they happen, and reads commands from connections one spawn-request's
     * worth at a time.
     *
     * @throws MethodAndArgsCaller in a child process when a main() should
     * be executed.
     */
    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);
                    
                
            
        
    

简而言之,/frameworks/base/cmds/app_process/app_main.cpp # main 解析init.rc 脚本传入的参数,触发AppRuntime #start函数进而执行ZygoteInit#main 方法。

2.4、fork 创建SystemServer进程

Zygote进程在fork 创建SystemServer进程后返回到SystemServer进程继续进行相关System进程启动工作,至此Zygote 进程启动完毕,Zygote进程在初始化时就会创建Android虚拟机、注册JNI函数、预加载系统资源文件和Java 类。所有应用进程都共享和继承这些资源,Zygote进程启动工作完毕后,也会变成守护进程,负责处理启动App 应用程序的请求,预知后事如何请参见下文。

三、Zygote启动应用进程

预知后事如何请参见下文,不过得先启动AMS服务。

以上是关于Android 进阶——系统启动之Android进程造物者Zygote 进程启动详解的主要内容,如果未能解决你的问题,请参考以下文章

Android 进阶——系统启动之SystemServer创建并启动Installer服务

Android 进阶——系统启动之SystemServer创建并启动Installer服务

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之核心SystemServer进程启动详解