美文网首页
Android系统启动流程(三)——SystemServer的启

Android系统启动流程(三)——SystemServer的启

作者: RainMi | 来源:发表于2019-11-12 18:00 被阅读0次

    接上篇:Android系统启动流程(二)——Zygote进程的启动流程

    启动SystemServer进程是Android系统启动过程中非常重要的一步,我们熟悉的SystemServiceManager以及AMS、WMS等服务都是由SystemServer进程来负责启动的,因此我们有必要来了解一下SystemServer的启动流程。

    1.SystemServer进程的创建

    SystemServer进程是由Zygote进程来启动的,在执行ZygoteInit.java的main方法时会去启动SystemServer:

    源码路径:\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

        public static void main(String argv[]) {
            ...
            try {
                ...
                boolean startSystemServer = false;
                String socketName = "zygote";
                String abiList = null;
                for (int i = 1; i < argv.length; i++) {
                    if ("start-system-server".equals(argv[i])) {
                        startSystemServer = true;//1.如果参数包含"start-system-server",则需要启动SystemServer
                    } else if ("--enable-lazy-preload".equals(argv[i])) {
                        enableLazyPreload = true;
                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                        abiList = argv[i].substring(ABI_LIST_ARG.length());
                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                    } else {
                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
                    }
                }
    
               ...
                if (startSystemServer) {
                    startSystemServer(abiList, socketName, zygoteServer);//2.启动SystemServer
                }
    
                ...
            } catch (Zygote.MethodAndArgsCaller caller) {
                caller.run();
            } catch (Throwable ex) {
                Log.e(TAG, "System zygote died with exception", ex);
                zygoteServer.closeServerSocket();
                throw ex;
            }
        }
    

    在注释1处,如果参数args中含有"start-system-server"字段,则会在注释2处通过调用startSystemServer方法来启动SystemServer,我们来看一下startSystemServer方法的源码:

        private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
                throws Zygote.MethodAndArgsCaller, RuntimeException {
           ...
            int pid;
    
            try {
                ...
                //1.调用Zygote的forkSystemServer方法来创建SystemServer进程
                pid = Zygote.forkSystemServer(
                        parsedArgs.uid, parsedArgs.gid,
                        parsedArgs.gids,
                        parsedArgs.debugFlags,
                        null,
                        parsedArgs.permittedCapabilities,
                        parsedArgs.effectiveCapabilities);
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException(ex);
            }
    
            /* 如果pid为0,则当前位于SystemServer进程 */
            if (pid == 0) {
                if (hasSecondZygote(abiList)) {
                    waitForSecondaryZygote(socketName);
                }
    
                zygoteServer.closeServerSocket();//关闭从Zygote进程复制而来的Socket
                handleSystemServerProcess(parsedArgs);//2.调用handleSystemServerProcess来初始化SystemServer进程
            }
    
            return true;
        }
    

    startSystemServer方法的代码比较简单,在注释1处,通过调用Zygote的forkSystemServer来创建了SystemServer进程,然后再注释2出通过调用handleSystemServerProcess来进一步对SystemServer进程进行一些初始化工作。我们先来看一下forkSystemServer的源码:

    源码路径:

    public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
                int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
            VM_HOOKS.preFork();
            // Resets nice priority for zygote process.
            resetNicePriority();
            int pid = nativeForkSystemServer(
                    uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
            // Enable tracing as soon as we enter the system_server.
            if (pid == 0) {
                Trace.setTracingEnabled(true);
            }
            VM_HOOKS.postForkCommon();
            return pid;
        }
    
        native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
                int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
    

    可以看到,在forkSystemServer方法中调用了native方法nativeForkSystemServer方法来创建SystemServer进程,而nativeForkSystemServer的底层则直接调用了fork方法来创建新的线程。

    再来看一下handleSystemServerProcess方法,源码如下:

        private static void handleSystemServerProcess(
                ZygoteConnection.Arguments parsedArgs)
                throws Zygote.MethodAndArgsCaller {
    
            ...
    
            if (parsedArgs.invokeWith != null) {
               ...
            } else {
                ClassLoader cl = null;
                if (systemServerClasspath != null) {
                    //1.创建PathClassLoader
                    cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
    
                    Thread.currentThread().setContextClassLoader(cl);
                }
    
               //2.调用ZygoteInit.zygoteInit来对SystemServer进行初始化
                ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
            }
        }
    

    在注释1处创建了一个PathClassLoader,然后在注释2出调用了ZygoteInit的zygoteInit方法来对SystemServer进行初始化。zygoteInit的源码如下:

    源码路径:\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

        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();//调用nativeZygoteInit
            RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        }
    
        private static final native void nativeZygoteInit();
    

    在zygoteInit方法中又调用了nativeZygoteInit方法,而nativeZygoteInit的作用主要是用来启动Binder线程池的。

    2.开启Binder线程池

    nativeZygoteInit方法所对应的C++代码如下:

    源码位置:\frameworks\base\core\jni\AndroidRuntime.cpp

    static AndroidRuntime* gCurRuntime = NULL;
    
    static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        gCurRuntime->onZygoteInit();
    }
    

    该方法直接调用了gCurRuntime对象的onZygoteInit方法,这个gCurRuntime是由AndroidRuntime的子类AppRuntime来实现的,它位于app_main.cpp文件中,我们来看一下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();
        }
    

    可以看到,onZygoteInit方法中又调用了ProcessState的startThreadPool来开启线程池,该方法的源码如下:

    源码路径:\frameworks\native\libs\binder\ProcessState.cpp

    void ProcessState::startThreadPool()
    {
        AutoMutex _l(mLock);
        if (!mThreadPoolStarted) {//1.判断线程池是否已经开启
            mThreadPoolStarted = true;
            spawnPooledThread(true);//2.调用spawnPooledThread方法
        }
    }
    
    void ProcessState::spawnPooledThread(bool isMain)
    {
        if (mThreadPoolStarted) {
            String8 name = makeBinderThreadName();//3.创建Binder线程池的名称
            ALOGV("Spawning new pooled thread, name=%s\n", name.string());
            sp<Thread> t = new PoolThread(isMain);//4.创建线程池对象
            t->run(name.string());//5.运行该线程池
        }
    }
    
    String8 ProcessState::makeBinderThreadName() {
        int32_t s = android_atomic_add(1, &mThreadPoolSeq);//编号+1
        pid_t pid = getpid();//获取pid
        String8 name;
        name.appendFormat("Binder:%d_%X", pid, s);//6.拼接Binder线程池名称
        return name;
    }
    

    首先在注释1处判断线程池是否已经开启,以此保证Binder线程池只会启动一次,然后在注释2出调用了spawnPooledThread方法来创建线程,并且参数为true。

    在注释3初通过makeBinderThreadName方法来创建线程的名称,通过注释6处的代码我们可以得知,Android中Binder线程的名称都是“Binder:”+线程id+“_”+线程编号的形式。

    在注释4处创建了线程池中的第一个线程,它是一个PoolThread 对象,isMain为true表示该线程为线程池的主线程,并在注释5出调用了run方法来运行该线程。

    我们来看一下PoolThread的源码:

    源码路径:\frameworks\native\libs\binder\ProcessState.cpp

    class PoolThread : public Thread
    {
    public:
        explicit PoolThread(bool isMain)
            : mIsMain(isMain)
        {
        }
        
    protected:
        virtual bool threadLoop()
        {
            IPCThreadState::self()->joinThreadPool(mIsMain);
            return false;
        }
        
        const bool mIsMain;
    };
    

    从上面的代码可以得知,PoolThread继承自Thread类。当运行PoolThread对象的run方法时,会调用该对象的threadLoop方法,并在threadLoop方法中调用IPCThreadState对象的joinThreadPool方法,来将该线程加入到Binder线程池中,至此,SystemServer进程就可以通过Binder与其他进程进行通信了。

    3.创建SystemServiceManager及各种系统服务

    回到ZygoteInit.java的zygoteInit方法中,在调用nativeZygoteInit来启动线程池后,又调用了RuntimeInit.applicationInit方法,该方法的代码如下:

    源码路径:\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);//1.调用invokeStaticMain方法
        }
    
        private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
                throws Zygote.MethodAndArgsCaller {
            Class<?> cl;
    
            try {
                cl = Class.forName(className, true, classLoader);//2.获取SystemServer对应的Java类
            } 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 });//3.找到main方法
            } 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);
            }
    
            /*
             * 4.抛出异常,该异常最终会在ZygoteInit.main中被捕获
             * 使用抛出异常的方法可以直接清理所有栈帧
             */
            throw new Zygote.MethodAndArgsCaller(m, argv);
        }
    

    从注释1处可以看到,applicationInit方法内又调用了invokeStaticMain方法,从invokeStaticMain方法的名字我们就可以猜出,该方法主要是使用反射来调用SystemServer的main方法的。在注释2处通过反射获取到了SystemServer对应的java类,并在注释3出通过反射找到了main方法。不过在invokeStaticMain方法中并没有直接去执行这个main方法,而是在注释4出抛出了一个异常对象Zygote.MethodAndArgsCaller,并将main方法和相关参数封装到了这个异常对象中,这个异常最终会在ZygoteInit.java的main方法中被捕获到,如下:

    public static void main(String argv[]) {
            ...
    
            try {
                ...
    
                if (startSystemServer) {
                    startSystemServer(abiList, socketName, zygoteServer);
                }
    
               ...
            } catch (Zygote.MethodAndArgsCaller caller) {//1.捕获Zygote.MethodAndArgsCaller异常
                caller.run();  //2.调用异常对象的run方法
            } catch (Throwable ex) {
                Log.e(TAG, "System zygote died with exception", ex);
                zygoteServer.closeServerSocket();
                throw ex;
            }
        }
    

    在注释1出捕获到了抛出的Zygote.MethodAndArgsCaller异常,然后在注释2处调用了该对象的run方法,MethodAndArgsCaller的源码如下:

    源码路径:\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;
                mArgs = args;
            }
    
            public void run() {
                try {
                    mMethod.invoke(null, new Object[] { mArgs });//执行main方法
                } 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);
                }
            }
        }
    

    可以看到,在MethodAndArgsCaller的run方法中直接通过mMethod.invoke来执行了传入的方法,即SystemServer的main方法,我们再来看SystemServer的main的代码:

    源码路径:\frameworks\base\services\java\com\android\server\SystemServer.java

        public static void main(String[] args) {
            new SystemServer().run();
        }
    
        private void run() {
            try {
                ...
                Looper.prepareMainLooper();//1.准备主线程的Looper
    
                System.loadLibrary("android_servers");//动态加载so库
    
                performPendingShutdown();
    
                createSystemContext();//2.创建系统context
    
                mSystemServiceManager = new SystemServiceManager(mSystemContext);//3.创建SystemServiceManager
                mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
                LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
                SystemServerInitThreadPool.get();
            } finally {
                traceEnd();
            }
    
            // 开始启动各种服务
            try {
                traceBeginAndSlog("StartServices");
                startBootstrapServices();//4.开启各种引导服务
                startCoreServices();//5.开启各种核心服务
                startOtherServices();//6.开启其他服务
                SystemServerInitThreadPool.shutdown();
            } catch (Throwable ex) {
                Slog.e("System", "******************************************");
                Slog.e("System", "************ Failure starting system services", ex);
                throw ex;
            } finally {
                traceEnd();
            }
    
            ...
    
            Looper.loop();//7.开始Loop无限循环
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    

    在main方法中创建了一个SystemServer对象并直接调用了该对象的run方法。

    在注释1处通过调用prepareMainLooper来准备主线程的Looper,在注释2处创建系统context,在注释3处创建了SystemServiceManager对象,该对象用来管理Android系统中的各种服务。

    注释4、5、6处都是在启动各种系统服务,Android中的系统服务大致可以分为3类:
    ①引导服务:如ActivityManagerService(用来管理四大组件)、PowerManagerService(用来处理与手机电量相关的逻辑)、PackageManagerService(用来管理手机上安装的应用)等
    ②核心服务:如BatteryService等
    ③其他服务:如InputManagerService(用来处理各种输入事件)、WindowManagerService(用于管理窗口)等

    我们以ActivityManagerService为例来看一下这些服务是如何被启动的,先来看一下startBootstrapServices的源码:

    源码路径:\frameworks\base\services\java\com\android\server\SystemServer.java

    private void startBootstrapServices() {
            ...
            // Activity manager runs the show.
            traceBeginAndSlog("StartActivityManager");
    
            //通过调用SystemServiceManager对象的startService方法来创建ActivityManagerService
            mActivityManagerService = mSystemServiceManager.startService(
                    ActivityManagerService.Lifecycle.class).getService();
            mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
            mActivityManagerService.setInstaller(installer);
            traceEnd();
            ...
    }
    

    从上面的代码可以看到,ActivityManagerService是由SystemServiceManager对象的startService方法来启动的,startService方法代码如下:

        @SuppressWarnings("unchecked")
        public <T extends SystemService> T startService(Class<T> serviceClass) {
            try {
                ...
                final T service;
                try {
                    Constructor<T> constructor = serviceClass.getConstructor(Context.class);//1.获取要启动的service的类的构造方法
                    service = constructor.newInstance(mContext);//2.创建服务实例
                } 
                ...
    
                startService(service);//3.调用另一个重载方法
                return service;
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            }
        }
    
        public void startService(@NonNull final SystemService service) {
            mServices.add(service);//4.将创建的service加入到mServices列表中
            long time = System.currentTimeMillis();
            try {
                service.onStart();//5.调用onStart方法来启动这个服务
            } catch (RuntimeException ex) {
                throw new RuntimeException("Failed to start service " + service.getClass().getName()
                        + ": onStart threw an exception", ex);
            }
            warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
        }
    

    在注释1处,通过反射获取要启动的服务的构造方法,然后再注释2处创建了一个新的实例。
    在注释3处调用了startService的另一个重载方法,并在注释4处将创建好的服务加入到了mServices列表中。
    在注释5处通过调用服务的onStart方法来开启了这个服务。

    至此SystemServer的启动流程就基本完成了。

    相关文章

      网友评论

          本文标题:Android系统启动流程(三)——SystemServer的启

          本文链接:https://www.haomeiwen.com/subject/blefictx.html