SystemServer进程启动流程

258 阅读5分钟

SystemServer 进程主要用于创建系统服务,例如 AMS、WMS 和 PMS 都是由它来创建的。

不同版本,代码略有差别,总体流程差别不大,以下代码基于 Android 8.0 源码

Zygotelnit.java 调用自身的 startSystemServer 方法,启动 SystemServer 进程。

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

private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
        throws Zygote.MethodAndArgsCaller, RuntimeException {
    /* ... */
    // 当前代码逻辑运行在子进程中
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
		// 关闭Zygote进程fork得到的Socket,该Scoket对SystemServer进程没有用处
        zygoteServer.closeServerSocket();
        // 启动SystemServer进程
        handleSystemServerProcess(parsedArgs);
    }
    return true;
}

调用 handleSystemServerProcess 方法来启动 SystemServer 进程。

private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)
        throws Zygote.MethodAndArgsCaller {
	/* ... */
    if (parsedArgs.invokeWith != null) {
        /* ... */
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            // 创建了PathClassLoader
            cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
			// 并把PathClassLoader设置为当前线程的ContextClassLoader
            Thread.currentThread().setContextClassLoader(cl);
        }
        // 将其余的参数传递给SystemServer。
        ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }
}

public static final void zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
    /* ... */
    RuntimeInit.commonInit();
    // 使用Native代码启动Binder线程池,这样SystemServer进程就可以使用Binder与其他进程进行通信了
    ZygoteInit.nativeZygoteInit();
    // 进入SystemServer的main方法
    RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

主要看两个重要方法:

  • ZygoteInit.nativeZygoteInit()
  • RuntimeInit.applicationInit()

一、启动 Binder线程池

nativeZygoteInit() 对应 AndroidRuntime.cpp 中的 com_android_internal_os_ZygoteInit_nativeZygoteInit 函数:

frameworks/base/core/jni/AndroidRuntime.cpp

static AndroidRuntime* gCurRuntime = NULL;
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    // gCurRuntime指向AndroidRuntime的子类AppRuntime
    gCurRuntime->onZygoteInit();
}

AppRuntime 类在 app_main.cpp 中定义。

frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    // 启动Binder线程池
    proc->startThreadPool();
}

startThreadPool系统实现在\frameworks\native\libs\binder\ProcessState.cpp文件中。

每一个支持Binder进程间通信机制的进程内都有一个唯一的ProcessState对象,当这个ProcessState对象的成员函数startThreadPool函数被第一次调用的时候,它就会在当前进程中启动一个线程池,并将mThreadPoolStarted这个成员变量设置为true。

//该函数是个无参数,无返回值的函数
void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    //判断线程池是否启动状态,启动的话就将标志信息设置为true属性。
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

二、main 方法启动

RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); 调用了 RuntimeInit 类的 applicationInit 静态方法来启动 SystemServer 进程。

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

protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws Zygote.MethodAndArgsCaller {
    /* ... */
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws Zygote.MethodAndArgsCaller {
    /* ... */
        // 通过反射得到SystemServer类,className的值为com.android.server.SystemServer
        cl = Class.forName(className, true, classLoader);
    /* ... */
        //找到SystemServer的main方法
        m = cl.getMethod("main", new Class[] { String[].class });
    /* ... */
    // 抛出MethodAndArgsCaller异常,并把main方法和参数带出去
    throw new Zygote.MethodAndArgsCaller(m, argv);
}
复制

捕获 MethodAndArgsCaller 异常的代码在 Zygotelnit.javamain 方法中。然后才会调用 SystemServer 的 main 方法。

不直接调用 main 方法,而采用抛出异常的方式,有两点原因:

  • 这种抛出异常的处理会清除所有的设置过程需要的堆栈帧。
  • 让 SystemServer 的 main方法看起来像是 SystemServer 进程的入口方法。
    • 在 Zygote 启动了 SystemServer 进程后,SystemServer 进程已经做了很多的准备工作,而这些工作都是在 SystemServer的 main 方法调用之前做的。
    • 这使得 SystemServer 的 main 方法看起来不像是 SystemServer 进程的入口方法。
    • 而这种抛出异常交由 Zygotelnit.java 的 main 方法来处理,会让 SystemServer 的 main 方法看起来像是 SystemServer 进程的入口方法。

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

public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();
	/* ... */
    try {
        /* ... */
        if (startSystemServer) {
            // 启动SystemServer进程,并捕获Zygote.MethodAndArgsCaller异常
            startSystemServer(abiList, socketName, zygoteServer);
        }
        Log.i(TAG, "Accepting command socket connections");
        zygoteServer.runSelectLoop(abiList);
        zygoteServer.closeServerSocket();
    } catch (Zygote.MethodAndArgsCaller caller) {
        // SystemServer进程完成初始化,调用run方法
        caller.run();
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        zygoteServer.closeServerSocket();
        throw ex;
    }
}

Zygote.MethodAndArgsCaller 异常类是 Zygote 类的静态内部类。

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

public static class MethodAndArgsCaller extends Exception implements Runnable {
    private final Method mMethod;
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;	// 这里的method就是传入的main方法
        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 才真正开始执行 main 方法。

三、解析 SystemServer 进程

进入 SystemServer 的 main 方法,只是调用了 run 方法而已。

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

public static void main(String[] args) {
    // 创建SystemServer对象,并执行run方法
    new SystemServer().run();
}

private void run() {
    /* ... */
    try {
        /* ... */
        // 设定时区
        String timezoneProperty = SystemProperties.get("persist.sys.timezone");
        if (!isValidTimeZoneId(timezoneProperty)) {
            /* ... */
            SystemProperties.set("persist.sys.timezone", "GMT");
        }

        // 设定语言
        if (!SystemProperties.get("persist.sys.language").isEmpty()) {
            final String languageTag = Locale.getDefault().toLanguageTag();
            SystemProperties.set("persist.sys.locale", languageTag);
            SystemProperties.set("persist.sys.language", "");
            SystemProperties.set("persist.sys.country", "");
            SystemProperties.set("persist.sys.localevar", "");
        }

        /* ... */

        // 设置虚拟机库文件路径
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        // 清除内存增长上限
        VMRuntime.getRuntime().clearGrowthLimit();

        // 有些设备依赖于运行时指纹生成,因此请确保在进一步启动之前已定义它。
        Build.ensureFingerprintProperty();

        // 设定环境变量访问用户条件
        Environment.setUserRequired(true);
        BaseBundle.setShouldDefuse(true);

        Parcel.setStackTraceParceling(true);

        // 设定binder服务永远运行在前台
        BinderInternal.disableBackgroundScheduling(true);

        // 设定binder线程池最大线程数
        BinderInternal.setMaxThreads(sMaxBinderThreads);

        /* ... */
        // 创建消息Looper
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        SystemServiceRegistry.sEnableServiceNotFoundWtf = true;

        // 加载动态库libandroid_servers.so
        System.loadLibrary("android_servers");
        
        /* ... */

        // 启动系统上下文
        createSystemContext();

        /* ... */

        // 创建SystemServiceManager对象
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        SystemServerInitThreadPool.start();
        /* ... */
    } finally {
        /* ... */
    }

    /* ... */

    // 启动各种服务
    try {
        t.traceBegin("StartServices");
        // 启动引导服务
        startBootstrapServices(t);
        // 启动核心服务
        startCoreServices(t);
        // 启动其他服务
        startOtherServices(t);
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        t.traceEnd();
    }
	/* ... */
    // 进入Loop循环,处理消息循环
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

run 方法中主要做了以下几件事:

  • 设置时间、时区、语言。
  • 设置虚拟机库文件路径 persist.sys.dalvik.vm.lib.2
  • 设定 binder 线程池最大线程数。
  • 创建消息 Looper
  • 加载 libandroid_servers.so 库。
  • 启动上下文。
  • 创建 SystemServiceManager 对象,负责系统 Service 的启动。
  • 启动引导服务、核心服务、其他服务,他们都是 SystemService类的子类。
    • 引导服务:ActivityManagerServicePowerManagerServicePackageManagerService 等。
    • 核心服务:DropBoxManagerServiceBatteryServiceUsageStatsServiceWebViewUpdateService
    • 其他服务:CameraServiceAlarmManagerServiceVrManagerService 等。
  • 开启 Looper 消息循环。

四、启动总结

SystemServer 进程被创建后,主要工作如下:

  • 启动 Binder 线程池,这样就可以与其他进程进行通信。
  • 创建 SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理。
  • 启动各种系统服务。其中startOtherServices中会启动launcher
  • 创建Looper,开启Looper消息循环。