0
点赞
收藏
分享

微信扫一扫

接劳巴,拔掉KL15,MCU重启。不接劳巴,拔掉KL15,MCU正常下电

蒸熟的土豆 03-30 06:30 阅读 4

一、概述

Zygote 是 Android 系统中的一个核心进程,它在系统启动时被初始化。Zygote 的主要任务是加载系统的核心类库(如 Java 核心库和 Android 核心库),然后进入一个循环,等待请求来创建新的 Android 应用程序进程。

当一个新的 Android 应用程序需要启动时,Zygote 会 fork 出一个新的进程,这个新的进程继承了 Zygote 的内存空间,包括已经预加载的类库。这种方式可以大大提高新进程的启动速度,因为不需要再次加载这些类库。

Zygote 进程是所有 Android 应用程序进程的父进程,它的启动和初始化对于 Android 系统的运行至关重要。

二、源码分析

在 init.rc 文件中会执行 class_start main 来启动 Zygote,源代码如下:

路径:/system/core/rootdir/init.rc

on nonencrypted
    class_start main
    class_start late_start

这个 main 就是 Zygote,可以通过 init.zygote64.rc 来查看,源代码如下:

路径:/system/core/rootdir/init.zygote64.rc

// 定义了一个名为 zygote 的服务,它运行的是 /system/bin/app_process64 可执行文件。
// “-Xzygote” 参数指定了这是一个 Zygote 进程,用于启动 Android 应用进程和系统服务。
// “--zygote” 标志表明这是一个 Zygote 服务实例。
// “--start-system-server” 意味着在 Zygote 启动时同时启动系统服务。
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    // 指定服务所属的主要控制类,即在 init 进程中优先启动。
    class main

    // 设置服务启动的优先级为-20(数值越低,优先级越高)。
    priority -20

    // 指定服务运行时的用户和组,这里是 root 用户,以及包含 root 组和其他两个附加权限组 readproc 和 reserved_disk。
    user root
    group root readproc reserved_disk

    // 创建两个命名 socket。
    // zygote socket 用于与系统进行通信,以便请求创建新的应用程序进程。
    // usap_pool_primary 用途可能与进程间通信或资源池管理有关。
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system

    // 定义了一系列在 zygote 服务重启时执行的操作。
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart write /sys/power/wake_lock zygote_kwl
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart media.tuner
    onrestart restart netd
    onrestart restart wificond

    // 指定 zygote 任务应具有高处理能力和最大性能配置文件。
    task_profiles ProcessCapacityHigh MaxPerformance

    // 设置 zygote 服务的关键窗口时间,在此期间如果服务未成功启动,则视为致命错误。
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

可以看到 audioserver、cameraserver、media、netd、wificond 这些进程都隶属于 Zygote 进程中,那就代表着:

  • 如果 Zygote died,这些进程将一起 died。
  • 如果这些进程 died,并不会影响 Zygote died。

如果 Zygote died 将会捕获到进程异常信号,将 Zygote 进程进行重启,Zygote main 入口位置:/frameworks/base/cmds/app_process/app_main.cpp

  1. app_main.cpp 源码分析

    路径:/frameworks/base/cmds/app_process/app_main.cpp
    
    int main(int argc, char* const argv[])
    {
        ...
    
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
        
        ...
    
        // 如果 zygote 为 true 则代表即将创建该进程。
        bool zygote = false;
        // 如果 startSystemServer 为 true 则代表创建 zygote 时也会创建 SystemServer。
        bool startSystemServer = false;
        // 系统正常启动都会将这两个 bool 默认给到 true,因为 rc 启动 main 后携带了--zygote 和 --start-system-server 两个参数。
        bool application = false;
        String8 niceName;
        String8 className;
    
        ++i;
        while (i < argc) {
            const char* arg = argv[i++];
            if (strcmp(arg, "--zygote") == 0) { // zygote 将为 true,名称就叫 zygote。
                zygote = true;
                niceName = ZYGOTE_NICE_NAME;
            } else if (strcmp(arg, "--start-system-server") == 0) { // startSystemServer 将为 true。
                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()) {
            ...
        } else {
            // 进入创建 zygote 模式。
            // 创建 /data/dalvik-cache,为后续会创建 Dalvik 虚拟机做准备。
            maybeCreateDalvikCache();
    
            if (startSystemServer) {
                args.add(String8("start-system-server"));
            }
    
            char prop[PROP_VALUE_MAX];
            
            ...
    
            // 将所有剩余参数传递给 args,例如 application 或 tool 或 start-system-server 或 abi。
            // 这些启动参数将会传递到其他进程中,后续取出参数决定是否启动 systemServer 等操作。
            for (; i < argc; ++i) {
                args.add(String8(argv[i]));
            }
        }
    
        if (!niceName.isEmpty()) {
            runtime.setArgv0(niceName.string(), true);
        }
    
        // zygote 为真,将创建 zygote,该 args 启动参数会包含 start-system-server。
        // 调用 runtime(AppRuntime) 的 start 来启动 zygote,将 args 传入,因为 args 包含了启动 SystemServer 的标志。
        if (zygote) {
            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
        } else if (!className.isEmpty()) {
            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.");
        }
    }
    

    以上代码就是启动 Zygote 和将 start-system-server 放入启动参数,后续会读取参数启动 SystemServer,继续分析一下 runtime.startcom.android.internal.os.ZygoteInit 进程,位于 /frameworks/base/core/jni/AndroidRuntime.cpp

  2. AndroidRuntime.cpp 源码分析

    路径:/frameworks/base/core/jni/AndroidRuntime.cpp
    
    // Vector<String8>& options 就是包含了 start-system-server 的启动参数,通过 app_main.cpp 传递过来的。
    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
    {
        ALOGD(">>>>>> START %s uid %d <<<<<<\n",
                className != NULL ? className : "(unknown)", getuid());
    
        // 默认会启动 SystemServer。
        static const String8 startSystemServer("start-system-server");
        // 是否私有,如果 SystemServer 会被创建时,将会设置为私有。
        bool primary_zygote = false;
    
        for (size_t i = 0; i < options.size(); ++i) {
            // options 就是传递过来的 args,默认是包含了 start-system-server。
            if (options[i] == startSystemServer) {
                primary_zygote = true;
            
            ...
        }
    
        // 获取环境变量,这里第一次执行时默认为空,所以 rootDir 不存在。
        const char* rootDir = getenv("ANDROID_ROOT");
        if (rootDir == NULL) {
            // 将直接拿到 /system 作为 rootDir 并设置环境变量。
            rootDir = "/system";
            if (!hasDir("/system")) {
                LOG_FATAL("No root directory specified, and /system does not exist.");
                return;
            }
            setenv("ANDROID_ROOT", rootDir, 1);
        }
    
        ...
    
        // 这里就开始启动虚拟机了。
        // JNI 功能初始化。
        JniInvocation jni_invocation;
        jni_invocation.Init(NULL);
        JNIEnv* env;
        // 创建 Dalvik 虚拟机(这里 --> DVM == JavaVM)。
        if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
            return;
        }
        onVmCreated(env);
    
        // 调用 startReg 函数用来为 DVM 注册 JNI。
        if (startReg(env) < 0) {
            ALOGE("Unable to register all android natives\n");
            return;
        }
    
        jclass stringClass;
        jobjectArray strArray;
        jstring classNameStr;
    
        // 通过反射拿到 String 类型。
        stringClass = env->FindClass("java/lang/String");
        assert(stringClass != NULL);
        // options 就是 app_main.cpp 传递过来的 args,包含了 start-system-server。
        // 将 options 转换为 array list 对象。
        strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
        assert(strArray != NULL);
        // 从 app_main.cpp 的 main 函数得知 className 为 com.android.internal.os.ZygoteInit。
        classNameStr = env->NewStringUTF(className);
        assert(classNameStr != NULL);
        // 将数据转换给 java 类型的 array 数组。
        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);
        }
    
        // 启动 com.android.internal.os.ZygoteInit,该线程成为 JVM 的主进程,在 VM 退出之前不会返回。
        char* slashClassName = toSlashClassName(className != NULL ? className : "");
        jclass startClass = env->FindClass(slashClassName);
        if (startClass == NULL) {
            ...
        } else {
            // 通过反射的方式,找到 ZygoteInit 的 main 函数。
            // 若获取到内容则执行 else。
            jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
                "([Ljava/lang/String;)V");
            if (startMeth == NULL) {
                ALOGE("JavaVM unable to find main() in '%s'\n", className);
            } else {
                // 通过 JNI 调用 ZygoteInit 的 main 函数,将 args(strArray) 传递到 java 层。
                // 因为 ZygoteInit 的 main 函数是 Java 编写的,因此需要通过 JNI 调用。
                // 所以这里继续跟到 java 层面:ZygoteInit.java。
                env->CallStaticVoidMethod(startClass, startMeth, strArray);
    
                ...
            }
        }
        // 若执行到这里,则会结束 Zygote 创建,关闭 JVM。
        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");
    }
    

    可以看到以上的代码主要就是初始化了 JNI(C++ 与 Java 交互)功能并创建并启动了 JVM 虚拟机,通过反射的方式去启动 ZygoteInit.java 的 main 方法,并将 args 参数(包含了是否启动 SystemServer 的参数)传递过去。而 JVM 虚拟机进程就是 com.android.internal.os.ZygoteInit,而 ZygoteInit 进程位于 /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 。

  3. ZygoteInit.java 源码分析

    路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    public static void main(String[] argv) {
        ZygoteServer zygoteServer = null;
    
        // 标记 zygote 开始了。
        ZygoteHooks.startZygoteNoThreadCreation();
    
        // 设置 zygote 自己的用户组 pid。
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }
    
        Runnable caller;
        try {
            // 读取系统是否已经启动完成。
            final long startTime = SystemClock.elapsedRealtime();
            final boolean isRuntimeRestarted = "1".equals(
                    SystemProperties.get("sys.boot_completed"));
    
            // 将行为写入 trace log 标记目前正处于 ZygoteInit 阶段。
            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
            TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                    Trace.TRACE_TAG_DALVIK);
            bootTimingsTraceLog.traceBegin("ZygoteInit");
            RuntimeInit.preForkInit();
    
            boolean startSystemServer = false;
            // zygote 进程就是一个 socket,名称就叫 zygote。
            String zygoteSocketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                // 从 AndroidRuntime.cpp 中传递上来,已经包含了 start-system-server。
                // 所以 startSystemServer = true。
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                }
    
                ...
            }
    
            // 为 true,是私有 zygote。
            final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
            
            ...
    
            // 记录的 trace log,只记录到这个地方。
            bootTimingsTraceLog.traceEnd();
    
            // 初始化 socket,从环境中获取套接字 FD(ANDROID_SOCKET_zygote)。
            // 若获取不到则创建一个用于和 systemServer 通信的 socket,当 systemServer fork 出来后 socket 进程将关闭。
            Zygote.initNativeState(isPrimaryZygote);
    
            ...
    
            // 根据环境变量(LocalServerSocket)获取 zygote 文件描述符并重新创建一个 socket,可以从这里看到 zygote 其实就是一个 socket。
            // 这个 name 为 zygote 的 Socket 用来等待 ActivityManagerService 来请求 Zygote 来 fork 出新的应用程序进程。
            // 所以 ActivityManagerService 里启动应用程序(APP),都是由该 zygote socket 进行处理并 fork 出的子进程。
            zygoteServer = new ZygoteServer(isPrimaryZygote);
    
            // 默认为 true,将启动 systemServer。
            if (startSystemServer) {
                // zygote 就是一个孵化器,所以这里直接 fork 出来 SystemServer。
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
    
                // 让 SystemServer 子进程运行起来。
                if (r != null) {
                    r.run();
                    return;
                }
            }
    
            Log.i(TAG, "Accepting command socket connections");
    
            // 让 zygote socket(注意不是 systemServer zygote)循环运行。
            // 等待 client 进程来请求调用,请求创建子进程(fork 出子进程(例如等待 AMS 的请求))。
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            ...
        } finally {
            if (zygoteServer != null) {
                // 停止关于 systemServer 的 socket,保留和 AMS 通信的 socket。
                // 在 initNativeState 阶段创建了一个和 systemServer 通信的 socket。
                // 接着拿到 systemServer socket 文件描述符重新创建了一个可以和 AMS 通信的 socket(/dev/socket/zygote)。
                zygoteServer.closeServerSocket();
            }
        }
    
        ...
    }
    

    以上代码讲述了 SystemServer Socket 的创建,将行为写入到 trace log 日志系统中,并通过 JNI 调用到底层的 fork 函数,孵化出 SystemServer 进程,如果 SystemServer 创建成功并已经运行了就会将当前 Socket 进行 close。期间会创建一个 Zygote Socket,用于等待其他子进程来连接,例如等待 AMS(Activity Manager Service)来连接该 Socket,然后继续 fork 出子进程(也就是应用程序,所以应用程序就是通过 Zygote 来 fork 出来的)。创建了 2 个 Socket,一个是 SystemServer Socket(Zygote.initNativeState(isPrimaryZygote) 来创建),一个是 Zygote Socket(new ZygoteServer(isPrimaryZygote) 来创建),注意区分。

    继续来看一下 zygoteServer = new ZygoteServer(isPrimaryZygote);

  4. ZygoteServer.java 源码分析

    路径:/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
    
    ZygoteServer(boolean isPrimaryZygote) {
        mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
    
        // 创建 socket,名称为 zygote,路径:/dev/sockets/zygote 。
        if (isPrimaryZygote) {
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
            
            ...
        }
        
        ...
    }
    
    路径:/frameworks/base/core/java/com/android/internal/os/Zygote.java
    
    static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
        // 文件描述符通过 ANDROID_socket_<socketName> 环境变量共享。
        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("Socket unset or invalid: " + fullSocketName, ex);
        }
    
        try {
            // 生成文件描述符。
            FileDescriptor fd = new FileDescriptor();
            fd.setInt$(fileDesc);
            return new LocalServerSocket(fd);
        } catch (IOException ex) {
            throw new RuntimeException(
                "Error building socket from file descriptor: " + fileDesc, ex);
        }
    }
    
    路径:/frameworks/base/core/java/android/net/LocalServerSocket.java
    
    public LocalServerSocket(FileDescriptor fd) throws IOException
    {
        // 创建 socket 并持续监听(等待 client 来调用)。
        impl = new LocalSocketImpl(fd);
        impl.listen(LISTEN_BACKLOG);
        localAddress = impl.getSockAddress();
    }
    

    简单点来说就是创建了一个 Zygoye Socket,位于 /dev/sockets/zygote,并调用了 runSelectLoop 让其循环运行,等待新进程发来的请求并进行连接 zygoteServer.runSelectLoop(abiList) 然后 fork 出子应用程序进程。

    路径:/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
    
    Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
        ArrayList<ZygoteConnection> peers = new ArrayList<>();
    
        // 拿到 socket 的文件描述符。
        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null);
    
        ...
    
        while (true) {
            ...
    
            if (pollReturnValue == 0) {
                ...
            } else {
                boolean usapPoolFDRead = false;
    
                while (--pollIndex >= 0) {
                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                        continue;
                    }
    
                    if (pollIndex == 0) {
                        // acceptCommandPeer 函数得到 ZygoteConnection 类并添加到 Socket 连接列表 peers 中。
                        // 接着将该 ZygoteConnection 的文件描述符添加到 fd 列表 fds 中,以便可以接收到 ActivityManagerService 发送过来的请求。
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        peers.add(newPeer);
                        socketFDs.add(newPeer.getFileDescriptor());
                    }
                    
                    ...
                }
    
                ...
            }
    
            ...
        }
    }
    

    zygoteServer.runSelectLoop(abiList) 持续等待进程来请求连接并 fork 出应用。

    至此 Zygote Socket 已经启动完毕了,该 Socket 会等待 AMS 进程发来的应用程序进程 fork。

    继续看看 SystemServer 是怎么被 fork 出来的 forkSystemServer(abiList, zygoteSocketName, zygoteServer);

  5. forkSystemServer 源码分析

    路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        ...
    
        // 创建 args 数组,这个数组用来保存启动 SystemServer 的启动参数,其中可以看出 SystemServer 进程的用户 id 和用户组 id 被设置为 1000。
        // 并且拥有用户组 1001 ~ 1010,1018,1021,1023,1024,1032,1065,3001 ~ 3003,3005 ~ 3007,3009 ~ 3012 的权限,进程名为 system_server。
        // 启动的类名为 com.android.server.SystemServer
        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,3005,3006,3007,3009,3010,3011,3012",
                "--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 {
            ...
    
            // 通过 JNI 形式去调用 init 进程下的 fork 函数,派生出 systemServer 进程。
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
    
        // pid == 0 代表已经运行在子进程(SystemServer)上了。
        // 代表 SystemServer 创建成功,创建成功后会关闭该 socket。
        if (pid == 0) {
            ...
    
            // 销毁 zygoteServer,保留和 AMS 通信的 socket(runSelectLoop)。
            // 当 SystemServer 创建过后,zygoteServerSocket 就没有用处了,进行关闭。
            zygoteServer.closeServerSocket();
            // 处理 system server 进程初始化工作并启动 SystemServer 进程。
            // 并启动了一个 binder 线程池供 system server 进程和其他进程通信使用。
            // 最后调用 RuntimeInit.applicationInit() 执行进程启动自身初始化工作。
            // applicationInit() 最后是通过反射调用了 SystemServer.java 中的 main() 方法。
            return handleSystemServerProcess(parsedArgs);
        }
    
        return null;
    }
    

    Zygote.forkSystemServer 就是调用了底层的 fork 函数。以上代码已知 SystemServer 子进程已经创建成功,将调用 handleSystemServerProcess 来启动 SystemServer.java 的入口。handleSystemServerProcess 会一直调用到 RuntimeInit.java 的 findStaticMain 方法中:

    路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
        ...
    
        if (parsedArgs.mInvokeWith != null) {
            ...
        } else {
            ...
    
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, cl);
        }
    }
    
    路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    
    public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
    
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }
    
    路径:/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    
    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        ...
    
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
    
    路径:/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    
    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;
    
        try {
            // 反射拿到 SystemServer 类
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            ...
        }
    
        Method m;
        try {
            // 反射拿到 SystemServer.java 的 main 函数,并启动。
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ...
        } catch (SecurityException ex) {
            ...
        }
    
        ...
    
        return new MethodAndArgsCaller(m, argv);
    }
    

    可以看到 handleSystemServerProcess 下面的子方法去调用了 com.android.server.SystemServer 的 main 方法,至此 SystemServer 就创建和启动完毕了,那么 SystemServer Socket 就会销毁并关闭。

三、总结

Zygote 进程是从 init.rc 脚本中启动的。Zygote 进程本质上是一个服务端 Socket,它会一直运行,等待新的进程请求。在创建 Zygote 进程时,会携带 StartSystemServer 参数,这个参数会触发 Zygote 进程创建 SystemServer 子进程。SystemServer 进程是通过 Zygote 进程 fork 出来的,它的启动是由 ZygoteInit 通过反射的方式调用 SystemServermain 方法实现的。

Zygote 进程在启动时创建了一个服务端 Socket,这个 Socket 用于与 SystemServer 进程的通信。当 SystemServer 进程创建完成后,Zygote 进程会关闭与 SystemServer 进程的 Socket 连接。此时,Zygote 进程已经完成了它的主要任务,它会进入一个循环,等待 Activity Manager Service (AMS) 或其他进程来请求新的应用程序进程。这个循环是通过调用 runSelectLoop 方法实现的。

请注意,Zygote 进程本身并不会关闭或销毁,它会一直运行,等待新的进程请求。而与 SystemServer 进程的 Socket 连接在 SystemServer 进程创建完成后就会关闭,因为此时已经没有必要维持这个连接了。

参考

  • 基于Android13的系统启动流程分析(五)之Zygote和SystemServer启动流程
举报
0 条评论