SystemServer启动流程之SystemServer启动(二)

来源:互联网 发布:java读取文件 编辑:程序博客网 时间:2024/04/30 15:35

1、概述

上一篇文章中我们已经分析了Zogote进程的启动流程SystemServer启动流程之zygote启动(一),ZygoteInit.main方法做了四件事情,其中第三件事就是启动我们的system_server,system_server进程作为zygote的嫡长子,其重要性是不言而喻的,今天我们就来分析一下其启动流程。

2、源码分析

我们紧接着上一篇文章分析到的位置开始,上一篇文章我们分析到了ZygoteInit.main方法的第三步startSystemServer方法,此方法就是zogote用来fork新进程system_server的重要步骤。

(1)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 */        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",            "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_server            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方法开始system_server进程的使命            handleSystemServerProcess(parsedArgs);        }        return true;    }

Zogote将system_server进程fork出来后,将调用handleSystemServerProcess方法开始发挥system_server进程的作用了。

(2)ZygoteInit.handleSystemServerProcess()

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

/**     * Finish remaining work for the newly forked system server process.     */    private static void handleSystemServerProcess(            ZygoteConnection.Arguments parsedArgs)            throws ZygoteInit.MethodAndArgsCaller {        //关闭从zygote那里继承下来的socket          closeServerSocket();        // set umask to 0077 so new files and directories will default to owner-only permissions.        Os.umask(S_IRWXG | S_IRWXO);        if (parsedArgs.niceName != null) {            //设置进程名为system_server             Process.setArgV0(parsedArgs.niceName);        }        //获得SystemServer类的路径,用于后面执行SystemServer的main方法        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");        if (parsedArgs.invokeWith != null) {            //......        } else {            ClassLoader cl = null;            if (systemServerClasspath != null) {                cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());                Thread.currentThread().setContextClassLoader(cl);            }            /*             * Pass the remaining arguments to SystemServer.             */             //传入SystemServer类的加载器,执行zygoteInit方法            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);        }        /* should never reach here */    }

此方法主要就是加载SystemServer类,然后执行RuntimeInit.zygoteInit方法,我们进入该方法。

(3)RuntimeInit.zygoteInit()

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

/**     * The main function called when started through the zygote process. This     * could be unified with main(), if the native code in nativeFinishInit()     * were rationalized with Zygote startup.<p>     *     * Current recognized args:     * <ul>     *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;     * </ul>     *     * @param targetSdkVersion target SDK version     * @param argv arg strings     */    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)            throws ZygoteInit.MethodAndArgsCaller {        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");        //常规初始化设置        redirectLogStreams();        commonInit();        //native层初始化        nativeZygoteInit();        //调用Java层的main方法        applicationInit(targetSdkVersion, argv, classLoader);    }

对此方法我们主要就分析一下nativeZygoteInit和applicationInit两个方法,我们进入nativeZygoteInit方法。

(4)RuntimeInit.nativeZygoteInit()

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

private static final native void nativeZygoteInit();static AndroidRuntime* gCurRuntime = NULL;//这里需要重点说一下,AndroidRuntime会在startReg方法中预加载大量的JNIAndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :        mExitWithoutCleanup(false),        mArgBlockStart(argBlockStart),        mArgBlockLength(argBlockLength){    //这里将gCurRuntime变量赋值为AndroidRuntime对象    gCurRuntime = this;}static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz){    gCurRuntime->onZygoteInit();}

这是一个native层的方法,其在native层的实现方法是AndroidRuntime.cpp文件的nativeZygoteInit方法,进入该方法可以发现,这里的gCurRuntime就是AndroidRuntime的对象,而AndroidRuntime.cpp是没有onZygoteInit方法的,所以其调用的是其子类AppRuntime的onZygoteInit方法。

//frameworks/base/cmds/app_process/app_main.cppnamespace android {    class AppRuntime : public AndroidRuntime    {        virtual void onZygoteInit()        {            // Re-enable tracing now that we're no longer in Zygote.            atrace_set_tracing_enabled(true);            sp<ProcessState> proc = ProcessState::self();            ALOGV("App process: starting thread pool.\n");            //启动一个线程用于Binder通信            proc->startThreadPool();        }    }}

system_server调用完nativeZygoteInit之后,便于Binder通信系统建立了联系,这样system_server就能使用Binder进行通信了。

(5)RuntimeInit.applicationInit()

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

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)            throws ZygoteInit.MethodAndArgsCaller {        // 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);        // We want to be fairly aggressive about heap utilization, to avoid        // holding on to a lot of memory that isn't needed.        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);        final Arguments args;        try {            args = new Arguments(argv);        } catch (IllegalArgumentException ex) {            Slog.e(TAG, ex.getMessage());            // let the process exit            return;        }        // Remaining arguments are passed to the start class's static main        //这里直接调用invokeStaticMain方法        invokeStaticMain(args.startClass, args.startArgs, classLoader);    }

(6)RuntimeInit.invokeStaticMain()

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

/**     * Invokes a static "main(argv[]) method on class "className".     * Converts various failing exceptions into RuntimeExceptions, with     * the assumption that they will then cause the VM instance to exit.     *     * @param className Fully-qualified class name     * @param argv Argument vector for main()     * @param classLoader the classLoader to load {@className} with     */    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)            throws ZygoteInit.MethodAndArgsCaller {        Class<?> cl;        try {            //加载com.android.server.SystemServer类            cl = Class.forName(className, true, classLoader);        } catch (ClassNotFoundException ex) {            throw new RuntimeException(                    "Missing class when invoking static main " + className,                    ex);        }        Method m;        try {            //获得main方法            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();        //判断main方法是否是public和static类型        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.         */        //抛出MethodAndArgsCaller异常,将SystemServer的main方法传递过去        throw new ZygoteInit.MethodAndArgsCaller(m, argv);    }

可以看到ZygoteInit.MethodAndArgsCaller是一个继承自Exception的类,invokeStaticMain最后并没有直接调用com.android.server.SystemServer的main 方法,而是抛出了一个ZygoteInit.MethodAndArgsCalle类型的异常。
那该异常是在哪里被捕获的呢?其实是在ZygoteInit的main方法中,也许之前我们都没注意。

public static void main(String argv[]) {    try{        if ("start-system-server".equals(argv[i])) {             startSystemServer = true;        }        if (startSystemServer) {            startSystemServer(abiList, socketName);        }    }catch (MethodAndArgsCaller caller) {        //捕获到异常后调用其run方法处理        caller.run();    } catch (RuntimeException ex) {        closeServerSocket();        throw ex;    }}

main函数中通过try-catch最终捕获到了MethodAndArgsCaller异常,并通过异常类的run函数来处理。

/**     * Helper exception class which holds a method and arguments and     * can call them. This is used as part of a trampoline to get rid of     * the initial process setup stack frames.     */    public static class MethodAndArgsCaller extends Exception            implements Runnable {        /** method to call */        private final Method mMethod;        /** argument array */        private final String[] mArgs;        //保存传递过来的参数        public MethodAndArgsCaller(Method method, String[] args) {            mMethod = method;            mArgs = args;        }        public void run() {            try {                //通过反射调用SystemServer的main方法                mMethod.invoke(null, new Object[] { mArgs });            } catch (IllegalAccessException ex) {                throw new RuntimeException(ex);            } catch (InvocationTargetException ex) {                Throwable cause = ex.getCause();                if (cause instanceof RuntimeException) {                    throw (RuntimeException) cause;                } else if (cause instanceof Error) {                    throw (Error) cause;                }                throw new RuntimeException(ex);            }        }    }

至此,进入到SystemServer的Java世界啦,开始执行SystemServer的main方法,这里我们总结一下。

3、总结

这里主要讲述了如何从ZygoteInit.startSystemServer方法执行到SystemServer.main方法。
1、首先从ZygoteInit.startSystemServer()方法调用到RuntimeInit.zygoteInit()方法,主要是做zogote的初始化操作。

2、紧接着调用RuntimeInit.applicationInit()方法,此方法通过调用invokeStaticMain()方法来加载SystemServer类,并通过抛出MethodAndArgsCaller异常的方式让ZygoteInit.main()方法捕获处理。

3、ZygoteInit.main()方法通过catch捕获该异常后,通过其run方法的 mMethod.invoke()来执行SystemServer的main方法。

0 0
原创粉丝点击