美文网首页
Android Zygote-2 源码分析 之 SystemSe

Android Zygote-2 源码分析 之 SystemSe

作者: 行走中的3卡 | 来源:发表于2023-07-24 15:37 被阅读0次

Android 系统三大核心进程: init 、 zygote 、 system_server

使用 ps -A 可以看到这几个进程信息

root             1     0 12524552  5668 do_epoll_+          0 S init

root          1322     1 16798980 70176 do_sys_po+          0 S zygote64
root          1323     1 1836592  21892 do_sys_po+          0 S zygote

system        1879  1322 25091236 450520 do_epoll_+         0 S system_server

下面将从 跟踪 Zygote 到 SystemServer 再到系统核心服务的创建,源码分析加深理解。

1. ZygoteInit.main 创建及启动 SysteServer进程

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    @UnsupportedAppUsage
    public static void main(String[] argv) {
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }

这里又调用了 forkSystemServer

    private static Runnable forkSystemServer(String abiList, String socketName,
        ...
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities); 

就到了 Zygote 里的处理

2. Zygote.forkSystemServer()

这里的逻辑很简单,将调用 native 方法 nativeForkSystemServer

    static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        ZygoteHooks.preFork();

        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits,
                permittedCapabilities, effectiveCapabilities);

        // Set the Java Language thread priority to the default value for new apps.
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);

        ZygoteHooks.postForkCommon();
        return pid;
    }

native的方法是在 com_android_internal_os_Zygote.cpp 文件里实现的

3. com_android_internal_os_Zygote.nativeForkSystemServer

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
  ...     
  pid_t pid = zygote::ForkCommon(env, true,
                                 fds_to_close,
                                 fds_to_ignore,
                                 true);
                              
  if (pid == 0) {
      // System server prcoess does not need data isolation so no need to
      // know pkg_data_info_list.
      SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,
                       effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                       false, nullptr, nullptr, /* is_top_app= */ false,
  else (pid > 0) {
        gSystemServerPid = pid;
        ...
  }

这里看出,两个关键函数 ForkCommon 和 SpecializeCommon, Fork 出一个新的进程.
pid == 0表示 SystemServer 进程已创建成功了,并把它的 pid 赋值给全局变量 gSystemServerPid

3.1 ForkCommon

pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
                         const std::vector<int>& fds_to_close,
                         const std::vector<int>& fds_to_ignore,
                         bool is_priority_fork,
                         bool purge) {
    SetSignalHandlers();
    ...
    pid_t pid = fork();

SetSignalHandlers() 函数将注册一个信号处理器:SigChldHandler,来监听子进程的死亡。

4 ZygoteInit.handleSystemServerProcess()

在1 中 forkSystemServer 函数中调用 Zygote.forkSystemServer 创建 SystemServer 进程后,
会调用 handleSystemServerProcess 处理SystemServer自己 的工作

    private static Runnable forkSystemServer(String abiList, String socketName,
            /* 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);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

pid == 0表示 SystemServer 进程已创建成功了,这在它的线程里去处理相关任务.
它的处理函数为:

    /**
     * Finish remaining work for the newly forked system server process.
     */
    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Os.umask(S_IRWXG | S_IRWXO);

        if (parsedArgs.mNiceName != null) {
            Process.setArgV0(parsedArgs.mNiceName);
        }

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            // Capturing profiles is only supported for debug or eng builds since selinux normally
            // prevents it.
            if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) {
                try {
                    Log.d(TAG, "Preparing system server profile");
                    final String standaloneSystemServerJars =
                            Os.getenv("STANDALONE_SYSTEMSERVER_JARS");
                    final String systemServerPaths = standaloneSystemServerJars != null
                            ? String.join(":", systemServerClasspath, standaloneSystemServerJars)
                            : systemServerClasspath;
                    prepareSystemServerProfile(systemServerPaths);
                } catch (Exception e) {
                    Log.wtf(TAG, "Failed to set up system server profile", e);
                }
            }
        }

        if (parsedArgs.mInvokeWith != null) {
            String[] args = parsedArgs.mRemainingArgs;
            // If we have a non-null system server class path, we'll have to duplicate the
            // existing arguments and append the classpath to it. ART will handle the classpath
            // correctly when we exec a new process.
            if (systemServerClasspath != null) {
                String[] amendedArgs = new String[args.length + 2];
                amendedArgs[0] = "-cp";
                amendedArgs[1] = systemServerClasspath;
                System.arraycopy(args, 0, amendedArgs, 2, args.length);
                args = amendedArgs;
            }

            WrapperInit.execApplication(parsedArgs.mInvokeWith,
                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(), null, args);

            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
        } else {
            ClassLoader cl = getOrCreateSystemServerClassLoader();
            if (cl != null) {
                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             */
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, cl);
        }

        /* should never reach here */
    }

加载了 SystemServer 对应的文件 systemServerClasspath
构建对应的 ClassLoader: getOrCreateSystemServerClassLoader
最后将剩余的参数交给 ZygoteInit.zygoteInit() 完成进程的初始化

5 ZygoteInit.zygoteInit

又回到了 一开始的文件

    public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

这里又会进行 native 的调用

6. AndroidRuntime.cpp -> nativeZygoteInit

上面的ZygoteInit.nativeZygoteInit()调用,实际上将会进入AndroidRuntime里的实现:
frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

这里的 gCurRuntime 是 AppRuntime 。 它的父类是 AndroidRuntime, 创建的时候 赋值 gCurRuntime

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

    // Pre-allocate enough space to hold a fair number of options.
    mOptions.setCapacity(20);

    assert(gCurRuntime == NULL);        // one per process
    gCurRuntime = this;
}

也就是说 gCurRuntime 是 AppRuntime 本身。
因此,onZygoteInit 也就是 AppRuntime 里实现的

7. AppRuntime.onZygoteInit

AppRuntime 类是在 文件 app_main.cpp里的定义的
frameworks/base/cmds/app_process/app_main.cpp

class AppRuntime : public AndroidRuntime
{
    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

onZygoteInit 里又启动一个线程池,用于 binder 通信。这样应用程序进程就在可以在 进程间通信了。

8. RuntimeInit.applicationInit

在5 里ZygoteInit.zygoteInit 的最后, 调用 RuntimeInit.applicationInit
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);

        final Arguments args = new Arguments(argv);

        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

再看 findStaticMain, 通过反射的方法,调用了 SystemServer.main 方法
(如果是普通应用程序,则是 反射 ActivityThread.main 方法)

    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        return new MethodAndArgsCaller(m, argv);
    }

9. SystemServer.main

frameworks/base/services/java/com/android/server/SystemServer.java

    /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }

从注释里看出, main 是从 zygote 的入口。

10. SystemServer.run

这里就到了SystemServer的核心逻辑, 创建了 系统的核心服务

    private void run() {
        ...
            // Initialize native services.
            System.loadLibrary("android_servers");  
            
            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);

        // Start services.
        try {
            t.traceBegin("StartServices");
            startBootstrapServices(t);
            startCoreServices(t);
            startOtherServices(t);
            startApexServices(t);
        } catch (Throwable ex) {            

10. 总结.

(1) Zygote 进程创建出 子进程system_server, 然后 system_server 进程创建系统核心服务。
(2) Zygote 进程创建 其它 子进程 的过程 类似, 最后 回调的是 应用程序主线程的 ActivityThread.main 方法
(3) 熟悉这个过程,对深入理解 Android 的 Framework 框架很有帮助,是个很好的切入点.

11. 参考:

(结合Zygote)
https://juejin.cn/post/6850418113059422221
Android App Process 启动流程攻略 - 掘金 (juejin.cn)
(这个讲得很不错)

相关文章

网友评论

      本文标题:Android Zygote-2 源码分析 之 SystemSe

      本文链接:https://www.haomeiwen.com/subject/zzxcpdtx.html