【Android面試題】Android Framework核心面試題——SystemServer進(jìn)程的啟動(dòng)流程

SystemServer進(jìn)程的啟動(dòng)流程

這道題想考察什么?

這道題想考察同學(xué)對(duì)SystemServer進(jìn)程的了解。

考生應(yīng)該如何回答

SystemServer進(jìn)程是由zygote進(jìn)程啟動(dòng)的,它作為zygote進(jìn)程的大兒子,它被賦予了重要的職責(zé),啟動(dòng)并管理app運(yùn)行所需要的絕大多數(shù)服務(wù),其中包含:AMS ,ATMS,WMS,PKMS,PMS等等大概有90多個(gè)服務(wù),這些服務(wù)的啟動(dòng)和管理流程的細(xì)節(jié)請(qǐng)看后面的分析。

1.SystemServer是做什么的

SystemServer進(jìn)程主要是用于創(chuàng)建和管理系統(tǒng)服務(wù)的,例如AMS、WMS、PMS。由于SystemServer進(jìn)程和應(yīng)用進(jìn)程由Zygote進(jìn)程啟動(dòng),所以接下來分析Zygote如何處理的SystemServer進(jìn)程。

2.Zygote處理SystemServer進(jìn)程

繼上一題《Zygote進(jìn)程的啟動(dòng)流程》的代碼,在zygote#main() 函數(shù)中通過調(diào)用forkSystemServer()函數(shù) fork SystemServer 進(jìn)程,那么我們看一下下面的代碼:

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        try {
            // 1.創(chuàng)建SystemServer進(jìn)程,并返回當(dāng)前進(jìn)程的pid
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        // 2.如果pid==0則說明Zygote進(jìn)程創(chuàng)建SystemServer進(jìn)程成功,當(dāng)前運(yùn)行在SystemServer進(jìn)程中
        if (pid == 0) {
            // 3.由于SystemServer進(jìn)程fork了Zygote進(jìn)程的地址空間,所以會(huì)得到Zygote進(jìn)程創(chuàng)建的Socket,
            // 而這個(gè)Socket對(duì)于SystemServer進(jìn)程是無用的,因此,在此處關(guān)閉了該Socket。
            zygoteServer.closeServerSocket();
            // 4.啟動(dòng)SystemServer進(jìn)程
            return handleSystemServerProcess(parsedArgs);
        }
    }

上面的代碼執(zhí)行過程會(huì)涉及到進(jìn)程的fork,在代碼1 處,Zygote.forkSystemServer()執(zhí)行的過程中會(huì)創(chuàng)建一個(gè)進(jìn)程,這個(gè)進(jìn)程就是systemServer進(jìn)程。那么fork完成后,此處的代碼會(huì)返回兩次,因?yàn)閒ork 會(huì)返回兩次,一次返回是執(zhí)行fork新創(chuàng)建的代碼,另外一次是zygote自己的代碼。第一次返回值如果是0 ,說明當(dāng)前運(yùn)行的是新的創(chuàng)建的進(jìn)程的代碼也就是systemServer進(jìn)程的代碼,第二次返回的值是一個(gè)大于0的值,說明當(dāng)前運(yùn)行的代碼是zygote進(jìn)程的代碼。因此就有了后面的if判斷也就是代碼2處,如果 pid 等于0 ,說明當(dāng)前進(jìn)程是運(yùn)行在systemServer進(jìn)程中。systemServer進(jìn)程是不需要zygoteServer的,于是就有了 closeServerSocket代碼的存在。然后,再執(zhí)行handleSystemServerProcess,運(yùn)行systemServer進(jìn)程。

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
        if (parsedArgs.mInvokeWith != null) {
            ...
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                // 1.使用了systemServerClassPath和targetSdkVersion創(chuàng)建了一個(gè)PathClassLoader
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
            }

            // 2.調(diào)用 ZygoteInit.zygoteInit 方法
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, cl);
        }
    }

以上代碼做了兩件事:1)基于sdk版本創(chuàng)建了一個(gè)ClassLoader;2)執(zhí)行zygoteInit方法。

public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        // 1.進(jìn)入native方法
        ZygoteInit.nativeZygoteInit();
        // 2.獲取封裝了SystemServer的main函數(shù)的runnable
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

在zygoteInit函數(shù)中,首先是調(diào)用nativeZygoteinit函數(shù)來初始化進(jìn)程環(huán)境,然后再執(zhí)行applicationInit函數(shù)獲取封裝了SystemServer的main函數(shù)的Runnable。

2-1.ZygoteInit.nativeZygoteInit

在上一題《zygote進(jìn)程的啟動(dòng)流程》中我們知道有一個(gè)流程,那就是在zygote初始化的時(shí)候會(huì)注冊(cè)JNI,其中就有將nativeZygoteInit()方法和native函數(shù)com_android_internal_os_ZygoteInit_nativeZygoteInit()建立了映射關(guān)系。所以此時(shí)調(diào)用nativeZygoteInit()會(huì)調(diào)用到AndroidRuntime的下面的代碼。

static AndroidRuntime* gCurRuntime = NULL;

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

gCurRuntime是AndroidRuntime的指針,具體指向的是其子類AppRuntime,它在app_main.cpp中定義。代碼如下:

// frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
    {
        // 1.創(chuàng)建了一個(gè)ProcessState實(shí)例
        sp<ProcessState> proc = ProcessState::self();
        // 2.啟動(dòng)了一個(gè)Binder線程池
        proc->startThreadPool();
    }

在這個(gè)代碼中執(zhí)行的是進(jìn)程的初始化,首先在代碼1處,創(chuàng)建了一個(gè)進(jìn)程ProcessState,其中就會(huì)創(chuàng)建一個(gè)binder;然后在代碼2處啟動(dòng)了Binder線程池,為Binder線程的運(yùn)行提供了動(dòng)力。

到目前為止SystemServer進(jìn)程已經(jīng)創(chuàng)建完成,那么接下來就需要運(yùn)行systemServer進(jìn)程了,所以我們回到RuntimeInit.applicationInit函數(shù)中進(jìn)行分析。

2-2.RuntimeInit.applicationInit
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;
        try {
            // 1.通過反射得到了SystemServer類
            cl = Class.forName(className, true, classLoader);
        }

        Method m;
        try {
            // 2.找到了 SystemServer中的main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        }

        // 3.將main()方法傳入MethodAndArgsCaller()方法中
        return new MethodAndArgsCaller(m, argv);
    }

以上代碼就是運(yùn)用反射,拿到systemServer的main 函數(shù),并且調(diào)用MethodAndArgsCaller,將main函數(shù)的調(diào)用封裝到一個(gè)Runnable中,方便后期的執(zhí)行。

static class MethodAndArgsCaller implements Runnable {
        private final Method mMethod;
        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                // 執(zhí)行SystemServer的main()方法
                mMethod.invoke(null, new Object[] { mArgs });
            }
        }
    }

這個(gè)Runnable的run方法是在ZygoteInit的main()方法中被執(zhí)行。代碼如下:

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
    try {
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
                if (r != null) {
                    r.run();  //1 執(zhí)行run
                    return;
                }
            }
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            if (zygoteServer != null) {
                zygoteServer.closeServerSocket();
            }
        }

如上面代碼1處,執(zhí)行run方法,這個(gè)時(shí)候就是執(zhí)行方法main(),所以,接下來我們看systemServer main函數(shù)的執(zhí)行。

3. SystemServer進(jìn)程執(zhí)行

// frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
        new SystemServer().run();
}

main函數(shù)就一行代碼執(zhí)行SystemServer進(jìn)程的潤(rùn)函數(shù):

private void run() {
        try {
            Looper.prepareMainLooper();

            // 1.加載動(dòng)態(tài)庫libandroid_servers.so
            System.loadLibrary("android_servers");

            // 2.創(chuàng)建SystemServerManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            
            // 3.初始化系統(tǒng)上下文
            createSystemContext();

        }

        try {
            // 3.使用SystemServiceManager啟動(dòng)引導(dǎo)服務(wù)
            startBootstrapServices(t);
            // 4.啟動(dòng)核心服務(wù)
            startCoreServices(t);
            // 5.啟動(dòng)其他服務(wù)
            startOtherServices(t);
        }

        // Loop forever.
        Looper.loop();
}

通過上面的代碼不難發(fā)現(xiàn),啟動(dòng)過程中,在大流程上systemServer和app進(jìn)程的啟動(dòng)很像,初始化了很多資源,也加載了很多資源,還創(chuàng)建了上下文,同時(shí)構(gòu)建了進(jìn)程的Looper 死循環(huán)確保進(jìn)程不會(huì)退出。當(dāng)然,在SystemServer中最重要的內(nèi)容還是通過代碼3,4,5啟動(dòng)了非常多的服務(wù),大概有90多個(gè)服務(wù),這些服務(wù)包括AMS,ATMS,WMS,PKMS,BMS等等一系列的服務(wù)。另外,在代碼2處創(chuàng)建了一個(gè)systemServiceManager對(duì)象,這個(gè)對(duì)象是用于在SystemServer進(jìn)程中管理90多個(gè)服務(wù)的啟動(dòng)的。

4.總結(jié)

SystemService進(jìn)程被創(chuàng)建后,主要的處理如下:

  1. 啟動(dòng)Binder線程池,這樣就可以與其他進(jìn)程進(jìn)行Binder跨進(jìn)程通信。
  2. SystemServer在啟動(dòng)過程中,先初始化一些系統(tǒng)變量,加載類庫,創(chuàng)建Context對(duì)象。
  3. 創(chuàng)建SystemServiceManager,它用來對(duì)系統(tǒng)服務(wù)進(jìn)行創(chuàng)建、啟動(dòng)和生命周期管理。
  4. 啟動(dòng)各種系統(tǒng)服務(wù):引導(dǎo)服務(wù)、核心服務(wù)、其他服務(wù),共90多種。應(yīng)用開發(fā)主要關(guān)注引導(dǎo)服務(wù)ActivityManagerService、PackageManagerService和其他服務(wù)WindowManagerService、InputManagerService即可。
  5. SystemServer在啟動(dòng)服務(wù)前,會(huì)嘗試與Zygote建立Socket通信,通信成功后才去啟動(dòng)服務(wù)。
  6. 啟動(dòng)的服務(wù)都單獨(dú)運(yùn)行在SystemServer的各自線程中,同屬于SystemServer進(jìn)程

最后

有需要面試題的朋友可以關(guān)注一下哇哇,以上都可以分享!??!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容