SystemServer 进程启动过程

156 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

之前的文章《浅析Android系统启动过程》简要讲解了Android系统整体启动过程,今天我们看一下其中一个重要的过程:SystemServer进程是如何启动的。

文中源码基于Android 8.0

上篇文章《Zygote进程启动过程》提到Zygote启动过程中调用了startSystemServer启动SystemServer进程,我们继续跟进里面的代码看SystemServer进程是如何启动的。

startSystemServer中通过fork方式创建了SystemServer进程,并调用handleSystemServerProcess处理SystemServer进程,其代码如下:

    private static void handleSystemServerProcess(
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);//---1---

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

            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);---2---

注释1创建了ClassLoader,用于加载类。注释2调用了ZygoteInit.zygoteInit方法:

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();
        ZygoteInit.nativeZygoteInit();//---1---
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);//---2---
    }

注释1处通过native方法,创建了Binder线程池,用于跨进程通信。注释2处调用RuntimeInit.applicationInit方法:

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

        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            return;
        }

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        invokeStaticMain(args.startClass, args.startArgs, classLoader);//---1---
    }

继续看注释1处invokeStaticMain方法:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);//---1---
        } 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 });---2---
        } 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);---3---
    }

注释1处通过反射获取传入的className类,从最开始的startSystemServer方法可以知道,这里的className就是args参数中的com.android.server.SystemServer,所以反射得到的类是SystemServer类。注释2处通过反射得到SystemServermain方法。注释3处将Methodargv作为参数,创建了Zygote.MethodAndArgsCaller并抛出,那抛出的这个Zygote.MethodAndArgsCaller是在哪里catch的?顺着源码返回去看可以知道这个Zygote.MethodAndArgsCaller是在启动Zygote进程时main方法里捕获的,这里只贴了关键代码,具体代码如下:

public class ZygoteInit {
    public static void main(String argv[]) {
        try {
            startSystemServer(abiList, socketName, zygoteServer);
        catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        }
    }
}

catch里执行了caller.run()方法,我们再看Zygote.MethodAndArgsCallerrun方法:

public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });//---1---
            } 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);
            }
        }

这里只调用了mMethod.invoke,回到之前的代码,其实就是用反射的方式调用了SystemServermain方法:

    public static void main(String[] args) {
        new SystemServer().run();
    }

再看SystemServerrun方法,由于代码很长,这里只贴关键代码:

    private void run() {
        Looper.prepareMainLooper();//1
    
        System.loadLibrary("android_servers");//2
        createSystemContext();//3
        mSystemServiceManager = new SystemServiceManager(mSystemContext);//4
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);//5
         
        startBootstrapServices();//6
        startCoreServices();//7
        startOtherServices();//8
        
        Looper.loop();//9
         

注释1处初始化Looper;注释2加载了android_servers.so库;注释3创建系统Context;注释4创建SystemServiceManager;注释5将SystemServiceManager添加到本地服务;注释6启动引导服务;注释7启动核心服务;注释8启动其他服务;注释9开启Looper循环。

学习更多知识,请关注我的个人博客:droidYu