SystemServer start the process of starting Zygote (a)

Disclaimer: This article is a blogger original article, reproduced welcome but must indicate the source Thank you! https://blog.csdn.net/dongxianfei/article/details/52607411

1 Overview

In the Android system, all of the application process and system service process SystemServer Zygote process fork are made out of, which is perhaps why should it be called Zygote (fertilized egg) reasons, but the system more important ActivityManagerService, PackageManagerService , WindowManagerService and PowerManagerService and so is the process of creating its child processes SystemServer come. Since Zygote process has such an important position in the Android system, this paper will analyze in detail its startup process.

Here we take a look at the process of drawing phone:

Zygote its child processes

As can be seen from the chart, ID Zygote process is 2452, and the parent process ID system_server, systemui, settings and other processes are also 2452, it can be said that these sub-processes are created by Zygote from the process.

We should all know, Android system is based on the Linux kernel, and the Linux system, all processes are child processes init process, that all processes are either directly or indirectly, by the init process fork out. Zygote process is no exception, it is in the process of system startup, created by the init process. Because this article is based on Android 5.1 version, so we can see here there is init.zygote32.rc, init.zygote32_64.rc, init.zygote64.rc, init.zygote64_32.rc and other documents under the system / core / rootdir / directory, we here we look at a init.zygote32.rc script.

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

In front of the key service is to tell the init process to create a process called "zygote", a program that zygote process to be executed is / system / bin / app_process, followed by the arguments to app_process.

Here we later learned to know Zygote process to create a program to be executed is the system / bin / app_process, and its source code is located frameworks / base / cmds / app_process / app_main.cpp file, the entry point is the main, we enter the method.

2, source code analysis

(1)app_main.main()

源码:frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
        // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
        // EINVAL. Don't die on such kernels.
        if (errno != EINVAL) {
            LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
            return 12;
        }
    }

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;

    // Everything up to '--' or first non '-' arg goes to the vm.
    //
    // The first argument after the VM args is the "parent dir", which
    // is currently unused.
    //
    // After the parent dir, we expect one or more the following internal
    // arguments :
    //
    // --zygote : Start in zygote mode
    // --start-system-server : Start the system server.
    // --application : Start in application (stand alone, non zygote) mode.
    // --nice-name : The nice name for this process.
    //
    // For non zygote starts, these arguments will be followed by
    // the main class name. All remaining arguments are passed to
    // the main method of this class.
    //
    // For zygote starts, all remaining arguments are passed to the zygote.
    // main function.
    //
    // Note that we must copy argument string values since we will rewrite the
    // entire argument block when we apply the nice name to argv0.

    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]));
    }

    // 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);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    Vector<String8> args;
    if (!className.isEmpty()) {
        // 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);
    } else {
        // We're in zygote mode.
        maybeCreateDalvikCache();

        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }

        char prop[PROP_VALUE_MAX];
        if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
            LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                ABI_LIST_PROPERTY);
            return 11;
        }

        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);

        // In zygote mode, pass all remaining arguments to the zygote
        // main() method.
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }

    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string());
        set_process_name(niceName.string());
    }

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }
}

Here is the final call to start the main method runtime object, the method and com.android.internal.os.ZygoteInit class as an argument, where the runtime object is the AppRuntime, we look at its source code (such in app_main. cpp file).

class AppRuntime : public AndroidRuntime{
    //......
}

Can be found in the class is inherited from AndroidRuntime, and its start method is a superclass of AndroidRuntime, so we start into the parent class.

(2)AndroidRuntime.start()

源码:frameworks/base/core/jni/AndroidRuntime.cpp

/*
 * 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)
{
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
            className != NULL ? className : "(unknown)", getuid());

    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;
           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);
    }

    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);

    /*通过调用startVm来启动虚拟机*/
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */

     /*通过startReg()来注册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 = 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 {

        /*调用传递过来的com.android.internal.os.ZygoteInit类的main方法*/
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 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");
}

This code is mainly to do three things:
1, call startVm way to start the virtual machine
2, to register call startReg JNI
3, call CallStaticVoidMethod method to invoke the main class method ZygoteInit

(3) AndroidRuntime.startReg ()

源码:frameworks/base/core/jni/AndroidRuntime.cpp

/*
 * Register android native functions with the VM.
 */
/*static*/ 
int AndroidRuntime::startReg(JNIEnv* env)
{
    //......

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}

Here loading a large array of gRegJNI files register_jni_procs way we look at their implementation.

static const RegJNIRec gRegJNI[] = {
    REG_JNI(register_com_android_internal_os_RuntimeInit),
    REG_JNI(register_android_os_SystemClock),
    REG_JNI(register_android_util_EventLog),
    REG_JNI(register_android_util_Log),
    REG_JNI(register_android_util_FloatMath),
    REG_JNI(register_android_content_AssetManager),
    REG_JNI(register_android_content_StringBlock),
    REG_JNI(register_android_content_XmlBlock),
    REG_JNI(register_android_emoji_EmojiFactory),
    REG_JNI(register_android_text_AndroidCharacter),
    REG_JNI(register_android_text_StaticLayout),
    REG_JNI(register_android_text_AndroidBidi),
    REG_JNI(register_android_view_InputDevice),
    REG_JNI(register_android_view_KeyCharacterMap),
    REG_JNI(register_android_os_Process),
    REG_JNI(register_android_os_SystemProperties),
    REG_JNI(register_android_os_Binder),
    REG_JNI(register_android_os_Parcel),
    REG_JNI(register_android_nio_utils),
    REG_JNI(register_android_graphics_Graphics),
    REG_JNI(register_android_view_DisplayEventReceiver),
    REG_JNI(register_android_view_RenderNode),
    REG_JNI(register_android_view_RenderNodeAnimator),
    //......
}

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    for (size_t i = 0; i < count; i++) {
        if (array[i].mProc(env) < 0) {
            return -1;
        }
    }
    return 0;
}

Here it can be seen from the code, which loops through the array gRegJNI registered through JNI for.

(4)ZygoteInit.main()

源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
        try {
            // Start profiling the zygote initialization.
            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.");
            }

            //(1)创建socket接口用来和ActivityManagerService通信
            registerZygoteSocket(socketName);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            //(2)预加载应用程序框架中的类和资源
            preload();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            gc();

            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
            Trace.setTracingEnabled(false);

            //(3)调用startSystemServer方法来启动SystemServer服务
            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            Log.i(TAG, "Accepting command socket connections");
            //runSelectLoop在之前创建的socket上进入无限循环等待AMS请求创建新的应用程序进程
            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

FIG represented herein by a step (picture from the network)
zygote_main

The next step will be more detailed analysis.

(5)ZygoteInit.registerZygoteSocket()

源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

/**
     * Registers a server socket for zygote command connections
     *
     * @throws RuntimeException when open fails
     */
    private static void registerZygoteSocket(String socketName) {
        if (sServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                sServerSocket = new LocalServerSocket(
                        createFileDescriptor(fileDesc));
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }

Here come the parameters passed socketName value "zygote", and accordingly create a LocalServerSocket object and assign it to sServerSocket static variables, and relevant content generated in the socket in init.rc.

(6)ZygoteInit.preload()

源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

static void preload() {
        Log.d(TAG, "begin preload");
        /* SPRD:modify preload class and preload resource in parallel mode @{ */
        new Thread("preloadClsses"){
            @Override
            public void run() {
                //加载Framework类
                preloadClasses();
                mConnectedSignal.countDown();
                }
        }.start();
        new Thread("preloadResources"){
            public void run() {
                //加载资源文件
                preloadResources();
                mConnectedSignal.countDown();
            }
        }.start();
        waitForLatch(mConnectedSignal);
        /* @} */
        //加载OpenGL和共享库
        preloadOpenGL();
        preloadSharedLibraries();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        WebViewFactory.prepareWebViewInZygote();
        Log.d(TAG, "end preload");
    }

Here are the main pre-load some Framework class and resource files so that applications using these classes and resources, direct access can be done.

We first look at preloadClasses this method.

/**
     * Performs Zygote process initialization. Loads and initializes
     * commonly used classes.
     *
     * Most classes only cause a few hundred bytes to be allocated, but
     * a few will allocate a dozen Kbytes (in one case, 500+K).
     */
    private static void preloadClasses() {
        final VMRuntime runtime = VMRuntime.getRuntime();

    /**
     * The path of a file that contains classes to preload.
     */
    //private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";

        InputStream is;
        try {
            //使用流来加载PRELOADED_CLASSES文件
            is = new FileInputStream(PRELOADED_CLASSES);
        } catch (FileNotFoundException e) {
            return;
        }

        Log.i(TAG, "Preloading classes...");
        long startTime = SystemClock.uptimeMillis();

        //......

        // Start with a clean slate.
        System.gc();
        runtime.runFinalizationSync();
        Debug.startAllocCounting();

        try {
            BufferedReader br
                = new BufferedReader(new InputStreamReader(is), 256);

            int count = 0;
            String line;
            //逐行读取字符串
            while ((line = br.readLine()) != null) {
                // Skip comments and blank lines.
                line = line.trim();
                if (line.startsWith("#") || line.equals("")) {
                    continue;
                }

                try {
                    //加载读取的类
                    Class.forName(line);
                    //......
                    }
                    count++;
                }
                //......
            }

         //......
         }
    }

Function is relatively simple, is to read the contents of the row preloaded-classes file, we look at the contents of the file.

preloaded-classes file

This file is preloaded-classes mainly frameworks \ base \ tools \ preload tools automatically generated, the tool determines whether the class loader for each time is greater than 1250ms, more than this time will be written to the file preloaded-classes, and finally to the zygote Preloading. There are thousands like it multi-line, visible Zygote process is initialized when the task is very heavy, which is leading one of the reasons Android system slow start.
preloadResources and preloadOpenGL and so will not explain, in general deal with are similar, then we start to enter the method of SystemServer.

(7)ZygoteInit.startSystemServer()

源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

/**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_BLOCK_SUSPEND,
            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
        );
        /* Hardcoded command line to start the system server */
        //SystemServer启动参数
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
            "--capabilities=" + capabilities + "," + capabilities,
            "--runtime-init",
            "--nice-name=system_server",// 进程名为system_server
            "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 */
            //Zygote通过forkSystemServer来启动SystemServer
            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)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

args [] array start SystemServer stored parameters, the parameters set SystemServier nothing more than the name, uid, and GID, and process the packet, and finally a string parameter specifies SystemServer com.android.server.SystemServer class.

然后Zygote通过forkSystemServer方法创建新的进程来启动SystemServer组件,紧接着执行handleSystemServerProcess方法(此方法用于执行SystemServer进程的方法,我们后续分析)。

(8)ZygoteInit.runSelectLoop()

源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

/**
     * 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>();
        FileDescriptor[] fdArray = new FileDescriptor[4];

        // sServerSocket是之前在registerZygoteSocket创建的服务端socket
        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        int loopCount = GC_LOOP_COUNT;
        //这里通过无限循环来等待AMS连接socket
        while (true) {
            int index;

            /*
             * Call gc() before we block in select().
             * It's work that has to be done anyway, and it's better
             * to avoid making every child do it.  It will also
             * madvise() any free memory as a side-effect.
             *
             * Don't call it every time, because walking the entire
             * heap is a lot of overhead to free a few hundred bytes.
             */
            if (loopCount <= 0) {
                gc();
                loopCount = GC_LOOP_COUNT;
            } else {
                loopCount--;
            }


            try {
                fdArray = fds.toArray(fdArray);
                /* 
                    selectReadable是一个native函数,内部调用select等待客户端 
                    的连接,客户端连接上之后就会返回。 
                    返回值: 
                    <0:  内部发生错误 
                    =0: 该客户端第一次连接到服务端 
                    >0:  客户端与服务端已经建立连接,并开始发送数据 
                */ 
                index = selectReadable(fdArray);
            } catch (IOException ex) {
                throw new RuntimeException("Error in select()", ex);
            }

            if (index < 0) {
                throw new RuntimeException("Error in select()");
            /*返回0,表明该客户端第一次请求服务端,服务端调用accept与客户端建立连接,客户端在zygote中以ZygoteConnection对象表示
            */
            } else if (index == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDescriptor());
            } else {
                boolean done;
                /* 返回>0,表明发送数据的客户端的index,peers.get(index)取得发送数据客户端的ZygoteConnection对象,之后调用runOnce方法来创建应用程序
                */  
                done = peers.get(index).runOnce();
                // 请求处理完成之后,移除与该客户端的连接
                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
    }

runSelectLoop函数的逻辑比较简单,主要有两点:
1、处理客户端的连接和请求,其中客户端在zygote进程中使用ZygoteConnection对象表示。
2、客户的请求由ZygoteConnection的runOnce来处理。

好啦,到此Zygote进程就启动完成了,接下来我们总结一下其启动过程。

3、总结

Zygote是Android系统中创建java世界的盘古,它创建了第一个java虚拟机。同时,它又是女娲,它成功的繁殖了framework的核心system_server进程。主要步骤如下:

1、创建AppRuntime对象,并调用其start函数,之后zygote的核心初始化都由AppRuntime中。

2、调用startVm创建java虚拟机,然后调用startReg来注册JNI函数。

3、通过JNI调用com.android.internal.os.ZygoteInit类的main函数,从此进入了java世界。

4、调用registerZygoteSocket创建可以响应子孙后代请求的socket,同时zygote调用preload函数预加载了常用的类、资源等,为java世界添砖加瓦。

5、调用startSystemServer函数分裂了一个子进程system_server来为java世界服务。

6, Zygote completed the start-up work java world, they call to make their runSelectLoop fell asleep, after receiving the request if future generations, it will work for them to wake up.

Guess you like

Origin blog.csdn.net/dongxianfei/article/details/52607411