Android系统启动流程(3) —— 解析SystemServer进程启动过程

相关文章

Android系统启动流程(1)  ——  解析init进程启动过程

Android系统启动流程(2)  ——  解析Zygote进程启动过程

Android系统启动流程(4)  ——  解析Launcher启动过程​​​​​​​

SystemServer 启动过程

       SystemServer 进程主要用于创建系统服务,我们熟知的 AMS、WMS和PMS 都是由它来创建的,因此掌握 SystemServer 进程是如何启动的,它在启动时做了哪些工作是十分必要的,这篇文章主要分析Android8.1系统的SystemServer进程的启动流程。

     1. Zygote 处理 SystemServer 进程

       在Android系统启动流程(2)中讲到了Zygote进程启动了SystemServer进程,本篇文章来讲解Zygote是如何处理SystemServer进程的。

       在ZygoteInit.java的forkSystemServer方法中启动了SystemServer进程,代码如下所示:

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

 private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        
        ...

        /* For child process */ 
        // 当前运行在SystemServer进程中
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            // 关闭Zygote进程创建的Socket
            zygoteServer.closeServerSocket(); // ... 1
            return handleSystemServerProcess(parsedArgs); // ... 2
        }

        return null;
    }
       SystemServer 进程复制了 Zygote 进程的地址空 间,因此也 得到 Zygote 进程创建的Socket ,这个 Socket 对于 SystemServer进程没有什么 用处,  因此, 要注释1处的代码来关闭 Socket ,接着 在注释2 处调用 handleSystemServerProcess 方法来启动 SystemServer 进程。 handleSystemServerProcess 方法的代码如下所:
frameworks/base/core/java/com/android/internal/os/Zygotelnit.java
    /**
     * Finish remaining work for the newly forked system server process.
     */
    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
        
        ...

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

        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); // ... 1

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

            /*
             * Pass the remaining arguments to SystemServer.
             */
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); // ... 2
        }

        /* should never reach here */
    }

       在注释1处创建了PathClassLoader,在注释2处调用了 Zygotelnit.zygotelnit 方法,代码如下所示:

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

    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        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(); // ... 1
        // 进入SystemServer的main方法
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); // ... 2
    }

       在注释1处调用 nativeZygotelnit 方法看方法的名称就知道调用的是 Native 层的代码,用来启动 Binder 线程池,这样 SystemServer 进程就可以使用 Binder 与其他进程进行通信了。注释2处是用于进入 SystemServer的main方法,现在分别对注释 1和注释2的内容进行介绍。

     1. 启动 Binder 线程池

       nativeZygotelnit是一个Native 方法,因此我们先要了解它对应的 JNI 文件,代码如下所示:

frameworks/base/core/jni/AndroidRuntime.cpp

int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}
       通过 JNI的 gMethods 数组,可以看出 nativeZygotelnit 方法对应的是 JNI 文件 An droidRuntime.cpp的com_ android _ internal_ os _z ygotelnit_ nativeZ ygoteln it 函数:
 

frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}
       这里 gCurR untime是 AndroidRuntime 类型的指针,具体指向的是 A ndroidRuntime的子类 AppRuntime ,它在 app _ main.cpp 中定义,我们接着来查看  AppRuntime的 onZygotelnit 方法,代码如下所示:
 
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(); // ... 1
    }
       注释1 处的代码用来启动一个 Binder 线程池,这样 SystemServer 进程就可以使用 Binder与其他进程进行通了。看到这里我们知道 Runtimelnit.java的 nativeZygotelnit 函数主要是用来启动Binder 线程池的。
 

     2. 进入 SystemServer的main 方法

       我们再回到 Runtimelni t.j ava 的代码,在注释2处调 用了 Runtimelnit. applicationlnit 方法,代码如下所示:
   
frameworks/base/core/java/com/android/internal/os/Runtimelnit.java
 
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
       
        ... 

        final Arguments args = new Arguments(argv);

        ...      

        return findStaticMain(args.startClass, args.startArgs, classLoader); // ... 1
    }

     在注释1处调用了findStaticMain发法,代码如下:

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

    private static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            // 通过反射得到SystemServer类
            cl = Class.forName(className, true, classLoader); // ... 1
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            // 找到SystemServer的mian方法
            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);
        }

        /*
         * 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.
         */
        return new MethodAndArgsCaller(m, argv); // ... 3
    }
       注释1处的 className为 com.android.server.SystemServer ,通过反射返回的 cl 为SystemServer 类。在注释2 处找到 SystemServ er 中的 main 方法。在注释3处将找到的 main 方法传入 MethodAndArgsCaller 类中,MethodAndArgsCaller 实现了Runnable接口,代码如下:
 
frameworks/base/core/java/com/android/internal/os/Runtimelnit.java
    static class MethodAndArgsCaller 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 {
                // 通过invoke调用SystemServer的main方法
                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);
            }
        }
    }
}

       在注释1处通过invoke调用SystemServer的main方法,那么MethodAndArgsCaller 的run方法又是在哪里调用的呢?在Runtimelnit中findStaticMain方法会将MethodAndArgsCaller返回给Zygotelnit的zygoteInit方法,Zygotelnit的zygoteInit又将MethodAndArgsCaller返回给Zygotelnit的handleSystemServerProcess方法,Zygotelnit的handleSystemServerProcess方法又将MethodAndArgsCaller返回给Zygotelnit的forkSystemServer方法,最后Zygotelnit的forkSystemServer方法又将MethodAndArgsCaller放回给Zygotelnit的main方法,Zygote的main方法代码如下:

 public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();
        ...

        try {           
            ...

            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer); // ... 1

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run(); // ... 2
                    return;
                }
            }

            ...           

        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            zygoteServer.closeServerSocket();
        }

      ...
    }

       在注释1处forkSystemServer方法返回的Runnable对象就是MethodAndArgsCaller对象,然后在注释2处调用r.run()方法实质上调用的就是MethodAndArgsCaller类中的run方法,这样就调用到了SystemServer的main方法了。

     2 解析 SystemServer 进程

       下面来查看 SystemServer的 main方法 ,代码如下:  
 
frameworks/base/services/java/com/android/server/SystemServer.java
    public static void main(String[] args) {
        new SystemServer().run();
    }

       在main方法中,只调用了SystemServer的run方法,代码如下:

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

    private void run() {
        try {

            ...            

            // 创建消息Looper
            Looper.prepareMainLooper();

            // 加载了动态库libandroid_servers.so
            // Initialize native services.
            System.loadLibrary("android_servers"); // ... 1

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // 创建系统的Context
            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext); // ... 2
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            // 启动引导服务
            startBootstrapServices(); // ... 3
            // 启动核心服务
            startCoreServices(); // ... 4
            // 启动其他服务
            startOtherServices(); // ... 5
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

       ...

    }

             在注释1处加载了动态库libandroid_servers.so 。接下来在注释2处创建SystemServiceManager, 它会对系统服务进行创建、启动和生命周期管理。在注释3处的startBootstrapServices 方法中启动了 ActivityManagerService 、PowerManagerService、PackageManagerService 等服务,在注释4处的 startCoreServices 方法中则启动了 DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService 。 在注释5处的 startOtherServices 方法中启动了 CameraService、AlarmManagerService、VrManagerService 等服务。这些服务的父类均为 SystemService 。从注释3、4 、5的方法中可以看出,Google把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务是一些非紧要和不需要立即启动的服务。这些系统服务总共有100多个,下表列出部分系统服务及其作用。

                                                                  部分系统服务及其作用

                             引导服务
                                                                作    用
Installer
系统安装 apk  时 的一 个服务类,启动完成 In sta ll er 服务之后才能启动其 他的系统服务
ActivityManagerService
负责四大组件的启动、切换、调度
PowerManagerService
计算系统中和 Power 相关的数据,然后决策系统应该如何反应
Ligh tsServ i ce
管理和显示背光 LED
DisplayManagerServce
用来管理所有显示设备
UserManagerServ i ce
多用户模式管理
SensorService
为系统提供各种感应器服务
PackageManagerService
用来对apk 进行安装、解析、删除、卸载等操作
...... ......
                            核心服务
 
DropBoxManagerService
用于生成和管理系统运行时的 些日志文件
Battery Service
管理电池相关的服务
UsageStatsService
收集用户使用每一个A pp的 频率、使用 时长
Web ViewUpdateService
Web View 更新服务

                            其他服务

 
CameraService
摄像头相关服务
A l armManagerService
全局定时器管理服务
InputManagerService
管理输入事件
WindowManagerService
窗口管理服务
VrManagerService
VR 模式管理服务
B lu etoothService
蓝牙管理服务
No tific at ion Ma n agerService
通知管理服务
DeviceStorageMonitorService
存储相关管理服务
LocationManagerService
定位管理服务
A udi oServ i ce
音频相关管理服务
...... ......
       这些系统服务启动逻辑是相似的,这里以启动 PowerManagerService 来进行举例,代码如下所示:
 
frameworks/base/services/java/com/android/server/SystemServer.java
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

SystemServiceManager的startService 方法启动了 PowerManagerService,startService 方法如下所示:

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service); // ... 1
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart(); // ... 2
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }
       在注释1处将 Pow erManagerServ ice  添加到 mS ervices 中,其中 mServ ices是一 个存储 SystemService 类型的 Array List ,这样就完成了 PowerManagerService 的注册工作 。在注释2 处调用 PowerManagerServ ice的 onStart 方法 成启动 PowerManag erService。
       除了用mSystemServiceManager的 startServi ce 方法 启动系统 服务之外,也可以通过如下形式来启动系统服务,以 PackageManagerServ ic 为例:
 

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

 mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
       直接 调用了 PackageManagerService的 main 方法,代码如下:
 
    public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        PackageManagerServiceCompilerMapping.checkProperties();

        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore); // ... 1
        m.enableSystemUserPackages();
        ServiceManager.addService("package", m); // ... 2
        final PackageManagerNative pmn = m.new PackageManagerNative();
        ServiceManager.addService("package_native", pmn);
        return m;
    }
       在注释1 处直接创建 PackageManagerService 并在注释2 处将 PackageManagerService 注册到 ServiceManager 中, ServiceManager 用来管理系统中的各种 Service ,用于系统 C/S 架构中的 B inder 通信机制: C li ent 端要使用某个 Service ,则需要先到 ServiceManager 查询 Service 的相关信息,然后根据 Service 的相关信息与 Service 所在的 Serv er 进程建立通信通
路,这样 Client 端就可以使用 Service 了。

     3 SystemServer 进程总结

       SystemServer 进程被创建后,主要做了如下工作:
       (1 )启动 Binder 线程池,这样就可以与其他进程进行通信。
       (2 )创建 SystemServiceManager ,用于对系统的服务进行创建、启动和生命周期管理。
       (3 )启动各种系统服务。

猜你喜欢

转载自blog.csdn.net/lixiong0713/article/details/106756718