Zygote进程对SystemServer进程的启动

android源码学习目录

介绍

什么是SystemServer,简单来说SystemServer就是Android系统启动各种Service的入口,同时也对各个service进行了管理,其中包括AMS,PMS,WMS.

SystemServer是怎么启动的

上文我们知道,zygote孵化器进程在他的main函数中调用startSystemServer函数启动了SystemServer进程,通过对zygote孵化器的了解,我们能确定,SystemServer是通过zygote进程fock自己来创建的一个新的子进程。

 */
    //zygote进程main函数调动 startSystemServer
    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        .....

        /* 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,1021,1023,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 */
              //这个重要,Zygote进程fock自己的内存地址,来创建新的子进程
            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 */
        //上面已经fock创建了SystemServer进程,这里的代码已经运行在SystemServer进程里了
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
             //关闭zygote进程原有的socket请求
            zygoteServer.closeServerSocket();、
            //启动systemServer main函数
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

从代码中我们了解,startSystemServer首先构建了启动SystemServer所需的参数,之后Zynote进程fock自己的内存地址,因为zynote中有socket链接,SystemServer不需要所以关闭,之后在启动。
forkSystemServer用户复制zynote进程的内存地址,也就是复制zynote进程,后续的代码就会执行在这个这个新的进程里,也就是SystemServer进程。
forkSystemServer一执行,后续的代码执行就是新的进程了,因为新进程复制了zynote进程,所有zynote进程之前执行的内容也是存在的,只是之前的也复制到了新的进程。

    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {
 

        if (parsedArgs.invokeWith != null) {
            .....

        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                //创建path类型的类加载器
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             */
            //更具参数启动main函数
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */
    }

handleSystemServerProcess函数处理了很多参数,我们需要了解的就是

  • 函数创建了path类型类加载器设置到了当前线程。
  • zygoteInit函数启动了该类的main函数,参数中我们了解是 "com.android.server.SystemServer"类的main函数
 public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

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

        RuntimeInit.commonInit();
        //启动binder线程池
        ZygoteInit.nativeZygoteInit();
        //调用执行main函数
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

这一步也很重要,它里面包含了启动binder线程池,这是systemServer与其他进程通信的基础,Binder,

   protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
         .....

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

applicationInit函数对jvm进行了一些参数设置,invokeStaticMain是最终执行的函数,它通过反射找到SystemServer的main方法,并抛出异常。

    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        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);
        }
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }

这个函数分析了SystemServer类,并找到了该类的main函数,但这里并没有进行main函数的执行,它爆出了异常 throw new Zygote.MethodAndArgsCaller, new Zygote.MethodAndArgsCaller类是在/framework/core/base/java/com/android/internal/os/Zygote类里面的,这是个异常类,到这里回忆ZynoteInit类的main函数里

  public static void main(String argv[]) {
                ....

            if (startSystemServer) {
                startSystemServer(abiList, socketName, zygoteServer);
            }

            Log.i(TAG, "Accepting command socket connections");
            zygoteServer.runSelectLoop(abiList);

            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {  //Zygote.MethodAndArgsCaller异常捕获
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }

zynote主线程进行了异常捕获,但SystemServer是复制的zynote进程,所以zynote的能力和代码它也有,同样SystemServer主线程的异常也在这里捕获,捕获一样后执行caller.run方法,

public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });  //执行方法带参数
            } catch (IllegalAccessException ex) {
           .....
        }

invok方法是Java通过反射执行类方法,这里我们了解SystemServer抛出异常时已经对这个方法进行了反射,也就是SystemServer类的main方法,也是是说这里才是main方法最终开始执行的代码。

  1. google为什么采用这种异常捕获的方式来反射执行main方法,我不太了解,据说是为了利用Java里的异常机制来清理新进程的运行环境,这里没有研究,有研究的希望发文到专题。
  2. 到这里SystemServer进程的准备已经完成了,这时就正式进入SystemServer进程的main函数了。

你可能感兴趣的:(Zygote进程对SystemServer进程的启动)