Android系統啓動流程(三)——SystemServer的啓動流程

接上篇:Android系統啓動流程(二)——Zygote進程的啓動流程java

啓動SystemServer進程是Android系統啓動過程當中很是重要的一步,咱們熟悉的SystemServiceManager以及AMS、WMS等服務都是由SystemServer進程來負責啓動的,所以咱們有必要來了解一下SystemServer的啓動流程。android

1.SystemServer進程的建立

SystemServer進程是由Zygote進程來啓動的,在執行ZygoteInit.java的main方法時會去啓動SystemServer:c++

源碼路徑:\frameworks\base\core\java\com\android\internal\os\ZygoteInit.javamarkdown

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方法的源碼:app

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的源碼:socket

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方法來建立新的線程。oop

再來看一下handleSystemServerProcess方法,源碼以下:post

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的源碼以下:ui

源碼路徑:\frameworks\base\core\java\com\android\internal\os\ZygoteInit.javaatom

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系統中的各類服務。

註釋四、五、6處都是在啓動各類系統服務,Android中的系統服務大體能夠分爲3類:

  1. 引導服務:如ActivityManagerService(用來管理四大組件)、PowerManagerService(用來處理與手機電量相關的邏輯)、PackageManagerService(用來管理手機上安裝的應用)等
  2. 核心服務:如BatteryService等
  3. 其餘服務:如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的啓動流程就基本完成了。

相關文章
相關標籤/搜索