Android 系统启动 - SystemServer 进程

前言

SystemServer 是 Android 系统非常重要和核心的服务,其进程名为 system_server,它会在创建后启动系统中的其他服务,然后成为所有服务的管理者,向应用程序和其他服务提供服务。

SystemServer 启动过程

Android 系统启动 - Zygote 进程 中,我们提到,Zygote 进程在创建虚拟机,注册 JNI 本地方法,预加载类和资源等操作后,会启动 SystemServer 进程:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    try {
        ···
        if (startSystemServer) {
            // 启动 SystemServer 进程
            startSystemServer(abiList, socketName);
        }
    } catch (MethodAndArgsCaller caller) {
        caller.run(); // 真正启动 SystemServer
    } 
    ···
}

SystemServer 进程的启动是由 startSystemServer 负责:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static boolean startSystemServer(String abiList, String socketName)
            throws 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,1032,3001,3002,3003,3006,3007",
            "--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 */
            // 请求创建SystemServer进程
            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 */
        // 进入SystemServer进程
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            // 处理SystemServer进程剩余工作
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

从该函数中可以看到,startSystemServer 最终通过 Zygote.forkSystemServer 方法创建了 SystemServer 进程,并且从传递启动 SystemServer 进程的参数可以得知:SystemServer 进程的 uid=pid=1000;进程名为 system_server;启动的类名为com.android.server.SystemServer。

对于 Zygote.forkSystemServer 方法,其内部其实是通过 JNI 方法调用 C++ 层代码,最终通过调用 fork 函数创建子进程,也即:SystemServer 进程。由于我们这边侧重于对流程的解析,所以我们就不深入分析 Zygote.forkSystemServer 的具体过程。感兴趣者可以查看:Android系统启动-SystemServer上篇

startSystemServer 通过 Zygote.forkSystemServer 成功创建完 SystemServer 进程后,就会进入 handleSystemServerProcess 函数,对 SystemServer 进程做进一步操作:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

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) {
        Process.setArgV0(parsedArgs.niceName); //设置当前进程名为"system_server"
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        // 进行dex优化
        performSystemServerDexOpt(systemServerClasspath);
    }

    if (parsedArgs.invokeWith != null) {
        String[] args = parsedArgs.remainingArgs;
        // 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(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
        }
        // 启动应用进程
        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            // 创建类加载器,并赋予当前线程
            cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        // 传递剩余参数给到SystemServer进程,做进一步处理
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }

    /* should never reach here */
}

该函数其实主要做了三件事:

  • 关闭从父进程 Zygote 复制而来的 Socket:closeServerSocket
  • 设置当前进程名为 system_serverProcess.setArgV0
  • 进行 dex 优化:performSystemServerDexOpt
  • 对 SystemServer 进程做进一步处理:RuntimeInit.zygoteInit

我们主要来看下 RuntimeInit.zygoteInit
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
    // 将 System.out,System.err 重定向到 Android Log
    redirectLogStreams();
    // 进行一些通用操作的初始化
    commonInit();
    // JNI 调用本地方法启动Binder线程池
    nativeZygoteInit();
    // 应用初始化
    applicationInit(targetSdkVersion, argv, classLoader);
}

zygoteInit 函数主要做了四件事:

  • 重定向系统输出流/错误流 到 Android Log 输出:redirectLogStreams
  • 进行一些通用操作的初始化:设置默认的未捕获异常处理,时区设置,设置默认 HTTP User-Agent 头部等等:commonInit
  • 使用 JNI 调用本地方法启动 Binder 线程池:nativeZygoteInit
  • 对 SystemServer 的进一步初始化:applicationInit

我们主要来看下:nativeZygoteInitapplicationInit

先查看下 nativeZygoteInit 源码实现:见名知意,该方法调用的是一个本地方法,其对应的 JNI 文件为:frameworks/base/core/jni/AndroidRuntime.cpp

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    { "nativeFinishInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
    { "nativeZygoteInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
    { "nativeSetExitWithoutCleanup", "(Z)V",
        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};

因此,nativeZygoteInit 对应的本地方法(C++)为:com_android_internal_os_RuntimeInit_nativeZygoteInit

···
static AndroidRuntime* gCurRuntime = NULL;
···
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
  //gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
    gCurRuntime->onZygoteInit();
}

此处的 gCurRuntimeAndroidRuntime 类型,但其真实类型为 AndroidRuntime 的子类型:AppRuntime。所以 nativeZygoteInit 最终调用的是 AppRuntime.onZygoteInit
frameworks/base/cmds/app_process/app_main.cpp

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

可以看到,nativeZygoteInit 最终通过 ProcessState.startThreadPool 启动了一个 Binder 线程池。到此,SystemServer 进程就具备了与其他进程通过 Binder 进程通信的功能了。

所以,nativeZygoteInit 的作用就是启动 Binder 线程池。

接下来我们来看下:applicationInit
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用
    nativeSetExitWithoutCleanup(true);

    // 设置虚拟机的内存利用率参数值为0.75
    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;
    }

    // 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
    // 调用类"com.android.server.SystemServer" 的 main 方法
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

applicationInit 最终调用了 invokeStaticMain 方法,此处:args.startClass 为 "com.android.server.SystemServer",我们进入 invokeStaticMain 方法查看下:
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

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

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        ···
    }

    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        ···
    }
    ···
    /*
     * 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.
     */
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

这里其实就是通过反射找到类 com.android.server.SystemServermain 方法,然后通过主动抛出一个 ZygoteInit.MethodAndArgsCaller 异常,该异常会被 ZygoteInit.main() 函数捕获,然后再捕获该异常处会通过 MethodAndArgsCaller.run 最终反射调用 SystemServer.main 函数,具体源码如下:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    try {
        ···
    } catch (MethodAndArgsCaller caller) {
        caller.run();
    } catch (RuntimeException ex) {
        ···
    }
}

public static class MethodAndArgsCaller extends Exception
        implements Runnable {
    ···
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            ···
        }
    }
}

到这里,SystemServer.main 函数就启动了,接下来的操作才是 SystemServer 真正发挥 Android 核心服务的体现。

那接下来我们就来分析下 SystemServer.main 函数,看下其做了哪些事情。

SystemServer 核心操作 过程

先来看下 SystemServer.main 函数:
frameworks/base/services/java/com/android/server/SystemServer.java

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

直接创建一个 SystemServer 实例,并调用其 run 方法:

private void run() {
    ···
    // Ensure binder calls into the system always run at foreground priority.
    // 确保当前进程的 binder 调用总是运行在前台优先级
    BinderInternal.disableBackgroundScheduling(true);
    ···
    // 创建主线程 Looper
    Looper.prepareMainLooper();

    // Initialize native services.
    // 加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
    System.loadLibrary("android_servers");
    ···
    // Initialize the system context.
    // 初始化系统上下文
    createSystemContext();

    // Create the system service manager.
    //创建系统服务管理
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    // 将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    // Start services.
    //  启动各种系统服务
    try {
        startBootstrapServices(); // 启动引导服务
        startCoreServices();      // 启动核心服务
        startOtherServices();     // 启动其他服务
    } catch (Throwable ex) {
        ···
    }
    ···
    // Loop forever.
    // 启动 Looper 循环
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

SystemServer.run 方法做了很多事情,其中最主要的就是:

  • 创建并启动主线程 Looper,使能线程间通讯:Looper.prepareMainLooperLooper.loop
  • 加载 android_servers.so 库:System.loadLibrary("android_servers")
  • 初始化系统上下文:createSystemContext
  • 创建系统服务管理 ServiceManagernew SystemServiceManager
  • 启动各种服务startBootstrapServicesstartCoreServicesstartOtherServices

我们主要来看下启动各种服务的大概过程:

首先看下 引导服务 启动过程:startBootstrapServices
frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
    // Wait for installd to finish starting up so that it has a chance to
    // create critical directories such as /data/user with the appropriate
    // permissions.  We need this to complete before we initialize other services.
    // 阻塞等待与installd建立socket通道
    Installer installer = mSystemServiceManager.startService(Installer.class);

    // Activity manager runs the show.
    // 启动服务ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    // Power manager needs to be started early because other services need it.
    // Native daemons may be watching for it to be registered so it must be ready
    // to handle incoming binder calls immediately (including being able to verify
    // the permissions for those calls).
    // 启动服务PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
    ···
    // Manages LEDs and display backlight so we need it to bring up the display.
    // 启动服务LightsService
    mSystemServiceManager.startService(LightsService.class);

    // Display manager is needed to provide display metrics before package manager
    // starts up.
    // 启动服务DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    // We need the default display before we can initialize the package manager.
    // Phase100:在初始化package manager之前,需要默认的显示
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    ···
    // Start the package manager.
    // 启动服务PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();

    // 启动服务UserManagerService,新建目录/data/user/
    ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
    ···
    // Set up the Application instance for the system process and get started.
    // 设置 AMS
    mActivityManagerService.setSystemProcess();

    // The sensor service needs access to package manager service, app ops
    // service, and permissions service, therefore we start it after them.
    // 启动传感器服务
    startSensorService();
}

startBootstrapServices 主要做的就是启动各种引导服务(共 7 个):
ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService,SensorService。

接下来看下 核心服务 启动过程:startCoreServices
frameworks/base/services/java/com/android/server/SystemServer.java

private void startCoreServices() {
    // Tracks the battery level.  Requires LightService.
    // 启动服务BatteryService,用于统计电量
    mSystemServiceManager.startService(BatteryService.class);

    // Tracks application usage stats.
    // 启动服务UsageStatsService,用于统计应用使用情况
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));
    // Update after UsageStatsService is available, needed before performBootDexOpt.
    mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();

    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    // 启动服务WebViewUpdateService
    mSystemServiceManager.startService(WebViewUpdateService.class);
}

startCoreServices 就是用来启动 BatteryService,UsageStatsService,WebViewUpdateService 这些核心服务。

最后来看下 其他服务 启动情况:startOtherServices
frameworks/base/services/java/com/android/server/SystemServer.java

 private void startOtherServices() {
        ...
        SystemConfig.getInstance();
        mContentResolver = context.getContentResolver(); // resolver
        ...
        mActivityManagerService.installSystemProviders(); //provider
        mSystemServiceManager.startService(AlarmManagerService.class); // alarm
        // watchdog
        watchdog.init(context, mActivityManagerService); 
        inputManager = new InputManagerService(context); // input
        wm = WindowManagerService.main(...); // window
        inputManager.start();  //启动input
        mDisplayManagerService.windowManagerAndInputReady();
        ...
        mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount
        mPackageManagerService.performBootDexOpt();  // dexopt操作
        ActivityManagerNative.getDefault().showBootMessage(...); //显示启动界面
        ...
        statusBar = new StatusBarManagerService(context, wm); //statusBar
        //dropbox
        ServiceManager.addService(Context.DROPBOX_SERVICE,
                    new DropBoxManagerService(context, new File("/data/system/dropbox")));
         mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler
         lockSettings.systemReady(); //lockSettings

        //phase480 和phase500
        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        ...
        // 准备好window, power, package, display服务
        wm.systemReady();
        mPowerManagerService.systemReady(...);
        mPackageManagerService.systemReady();
        mDisplayManagerService.systemReady(...);
        
        //重头戏[见小节2.1]
        mActivityManagerService.systemReady(new Runnable() {
            public void run() {
              ...
            }
        });
    }

startOtherServices 的源码很长,但其主要做的就是启动一系列的服务(共 70 余个),如:AlarmManagerService,VibratorService 等。

SystemServer 启动完成各种服务后,最后就会开启 SystemServer 进程主线程消息循环 Looper.loop,使能 SystemServer 进程线程间通讯。

到此,SystemServer 进程已分析完毕。

总结

SystemServer 进程是由 Zygote 进程孵化(fork)出来的,具体为:Zygote 进程会通过 JNI 调用本地方法,fork 出一个子进程,也即 SystemServer 进程,然后 SystemServer 进程会通过一些列的操作,最终调用到 SystemServer.main函数,在此完成了 SystemServer 最主要的一些操作,让其成为 Android 承载核心业务的服务。

简单来讲,SystemServer 进程其主要做了以下几件事:

  • 创建自身的 Binder 线程池,使能进程间通讯
  • 创建系统服务管理:SystemServiceManager,用于管理系统中的所有服务
  • 启动各种服务
  • 启动线程间通讯

参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容