安卓啟動(dòng)流程梳理之 System Server進(jìn)程

安卓啟動(dòng)流程梳理之 System Server進(jìn)程

安卓系統(tǒng)從開機(jī)到桌面顯示是一個(gè)長(zhǎng)而復(fù)雜的流程,本文參考安卓源碼記錄安卓啟動(dòng)流程的梳理學(xué)習(xí)。(文章涉及的源碼基于 Android 10.0)由于 Android 啟動(dòng)流程很長(zhǎng),所以分幾篇來記錄,本篇記錄安卓系統(tǒng)中啟動(dòng)系統(tǒng)眾多服務(wù)的進(jìn)程 System Server 的啟動(dòng)流程。

System server 進(jìn)程進(jìn)程是安卓系統(tǒng)進(jìn)入桌面前的最后流程,在 system server 進(jìn)程啟動(dòng)過程中,啟動(dòng)了系統(tǒng)的眾多服務(wù)進(jìn)程。如 AMScamera server等。

System server 啟動(dòng)入口

從前面 zygote 進(jìn)程啟動(dòng)流程中得知, system server 進(jìn)程是在 ZygoteInit.java main() 函數(shù)進(jìn)入循環(huán)等待之前啟動(dòng)的。zygote 進(jìn)程通過 forkSystemServer 創(chuàng)建了一個(gè) Runnable 對(duì)象,并調(diào)用了其 run 方法。

public static void main(String[] argv) { 
    ...
    if (startSystemServer) {
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
        if (r != null) {
            r.run();
            return;
        }
    }
    ...
    caller = zygoteServer.runSelectLoop(abiList);   
    ...
}

forkSystemServer()

private static Runnable forkSystemServer(String abiList, String socketName,
                                         ZygoteServer zygoteServer) {
    ...
    String args[] = {
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
            + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
        "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs = null;
    int pid;
    try {
        parsedArgs = new ZygoteArguments(args);
        Zygote.applyDebuggerSystemProperty(parsedArgs);
        Zygote.applyInvokeWithSystemProperty(parsedArgs);
        boolean profileSystemServer = SystemProperties.getBoolean(
            "dalvik.vm.profilesystemserver", false);
        if (profileSystemServer) {
            parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
        }
        
        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer( // 1
            parsedArgs.mUid, parsedArgs.mGid,
            parsedArgs.mGids,
            parsedArgs.mRuntimeFlags,
            null,
            parsedArgs.mPermittedCapabilities,
            parsedArgs.mEffectiveCapabilities);
    }
    
    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) { // 2
            waitForSecondaryZygote(socketName);
        }
        zygoteServer.closeServerSocket(); // 3
        return handleSystemServerProcess(parsedArgs); // 4
    }
    return null;
}

forkSystemServer() 方法主要執(zhí)行了以下幾個(gè)任務(wù):

  1. 準(zhǔn)備 system server 啟動(dòng)的參數(shù),注釋1之前的代碼。
  2. 調(diào)用 Zygote forkSystemServer()system server 進(jìn)程,注釋1處。
  3. 如果系統(tǒng)初始化了 SecondZygote,則通過 SecondZygote 建立連接,注釋2處。
  4. 關(guān)閉從 zygote 進(jìn)程復(fù)制的 socket,因?yàn)?system server 通過 binder 與其它進(jìn)程通信(zygote 進(jìn)程除外),注釋3處。
  5. 最后調(diào)用 handleSystemServerProcess() 處理 system server 進(jìn)程初始化工作。

handleSystemServerProcess()

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    ...
    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        if (performSystemServerDexOpt(systemServerClasspath)) {
            sCachedSystemServerClassLoader = null;
        }
    }
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                                    VMRuntime.getCurrentInstructionSet(), null, args);
    } else {
        ...
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                                     parsedArgs.mRemainingArgs, cl);
    }
}

handleSystemServerProcess() 方法中首先會(huì)對(duì) SystemServerClassdex優(yōu)化,然后根據(jù) parsedArgs.mInvokeWith 是否為空走不同的分支,跟蹤代碼可知 parsedArgs.mInvokeWith == null,即最后執(zhí)行到了 ZygoteInit.zygoteInit()

ZygoteInit.zygoteInit()

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
                                        ClassLoader classLoader) {
    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit();
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

zygoteInit() 方法調(diào)用了 RuntimeInit.commonInit()ZygoteInit.nativeZygoteInit() 執(zhí)行一些進(jìn)程啟動(dòng)相關(guān)初始化工作,其中在 ZygoteInit.nativeZygoteInit() 調(diào)用 com_android_internal_os_RuntimeInit_nativeZygoteInit native函數(shù),啟動(dòng)了一個(gè) binder 線程池,供system server 進(jìn)程和其他進(jìn)程通信使用。最后調(diào)用 RuntimeInit.applicationInit() 執(zhí)行進(jìn)程啟動(dòng)自身初始化工作。

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
                                          ClassLoader classLoader) {
    ...
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
                                         ClassLoader classLoader) {
    Class<?> cl;
    try {
        cl = Class.forName(className, true, classLoader);
    }
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    }
    return new MethodAndArgsCaller(m, argv);
}

applicationInit() 最后是通過反射調(diào)用了 SyetemServer.java 中的 main() 方法。

SyetemServer.java 解析

public static void main(String[] args) {
       new SystemServer().run();
}
private void run() {
    try {
        ... 
        Looper.prepareMainLooper(); // 1
        System.loadLibrary("android_servers"); // 2
        ...
        createSystemContext(); // 3
        mSystemServiceManager = new SystemServiceManager(mSystemContext); // 4
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                                           mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        ...
        SystemServerInitThreadPool.get(); // 5
    }

    try {
        startBootstrapServices(); //6
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown(); // 7
    }
    ...
    Looper.loop()  // 8
}

SystemServer.main() 方法中創(chuàng)建了 SystemServer 實(shí)例,并調(diào)用了其 run() 方法。SystemServer進(jìn)程相關(guān)的初始化任務(wù)都是在 run() 方法中完成的,其主要執(zhí)行了以下任務(wù)。

  1. 創(chuàng)建當(dāng)前線程 Looper 對(duì)象。
  2. 通過 System.loadLibrary() 加載靜態(tài)庫(kù)。
  3. 創(chuàng)建系統(tǒng)上下文對(duì)象。
  4. 創(chuàng)建 SystemServiceManager 對(duì)象,用于管理系統(tǒng)的各種服務(wù)。
  5. 創(chuàng)建服務(wù)初始化線程池,使得系統(tǒng)服務(wù)的初始化過程可并行。
  6. 通過 SystemServiceManager 啟動(dòng)各種系統(tǒng)服務(wù),包括啟動(dòng)必需的服務(wù)、核心服務(wù)和其他服務(wù)三類(AMSPMS就是在這里啟動(dòng)的)。
  7. 回收并關(guān)閉服務(wù)初始化線程池。
  8. 通過 Looper.loop() 進(jìn)入阻塞式無限循環(huán),直到有新的任務(wù)執(zhí)行。

至此,system server 進(jìn)程的啟動(dòng)流程就結(jié)束了。

系統(tǒng)服務(wù)分類

system server 啟動(dòng)過程中,系統(tǒng)服務(wù)被分為三類、引導(dǎo)服務(wù)、核心服務(wù)、其他服務(wù)。

引導(dǎo)服務(wù):

  • Installer:安裝 apk 的服務(wù)
  • ActivityManagerService:負(fù)責(zé)四大組件的啟動(dòng)、切換、調(diào)度。
  • PackageManagerService:安裝、卸載、解析、管理系統(tǒng)中的 apk
  • PowerManagerService:系統(tǒng)中 power 相關(guān)的管理。
  • DisplayManagerService:顯示設(shè)備的管理。
  • SensorService:為系統(tǒng)提供各種傳感器的服務(wù)。

核心服務(wù):

  • BatteryService:電池相關(guān)的管理。
  • UsageStatsService:用戶行為和日志收集。
  • WebViewUpdateServicewebview更新服務(wù)。

其他服務(wù):

  • CameraService:攝像頭的管理并向系統(tǒng)提供相機(jī)能力。
  • AlarmManagerService:全局定時(shí)器服務(wù)。
  • WindowManagerService:窗口管理服務(wù)。
  • LocationManagerService:定位服務(wù)。
  • AudioService:音頻相關(guān)管理服務(wù)。

單個(gè)服務(wù)啟動(dòng)流程

單個(gè)的服務(wù)通過 SystemServiceManager.startService() 接口啟動(dòng),流程包括3步。

  1. 通過 serviceClass 對(duì)象獲取其構(gòu)造方法,調(diào)用構(gòu)造方法創(chuàng)建 service 實(shí)例。
  2. 將新建的 service 添加到服務(wù)列表 mServices 中。
  3. 調(diào)用 service.onStart() 方法啟動(dòng)服務(wù)。
public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        final T service;
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        }
        startService(service);
        return service;
    }
}

public void startService(@NonNull final SystemService service) {
    mServices.add(service);
    long time = SystemClock.elapsedRealtime();
    try {
        service.onStart();
    }
}

總結(jié)

image-20210821153019780.png

system server 啟動(dòng)流程主要包括以下流程:

  1. zygote 進(jìn)程啟動(dòng)過程中,調(diào)用 forkSystemServer() 進(jìn)入 system server 的創(chuàng)建流程
  2. 通過 Zygote.forkSystemServer() 復(fù)制 zygote 進(jìn)程,創(chuàng)建system server 進(jìn)程。
  3. 調(diào)用 handleSystemServerProcess() 進(jìn)入到 system server 進(jìn)程的初始化流程。
  4. 通過 ZygoteInit.zygoteInit() 調(diào)用到 RuntimeInit.applicationInit(), 然后在 findStaticMain() 方法中創(chuàng)建了包含 SystemServer.java main方法的 MethodAndArgsCaller 實(shí)例,最后返回到 forkSystemServer() 調(diào)用處,調(diào)用 MethodAndArgsCaller 實(shí)例的 run() 方法執(zhí)行到 SystemServer.main() 方法中。
  5. SystemServer.main() 方法執(zhí)行到了 SystemServer.run() 方法。在 run()方法中,創(chuàng)建了 SystemServiceManager 實(shí)例,并通過 SystemServiceManager 啟動(dòng)了各種系統(tǒng)服務(wù)。
  6. 最后 system server 進(jìn)程通過 Looper.loop() 進(jìn)入無限循環(huán),等待其他進(jìn)程通過 binder 發(fā)送新的任務(wù)。
?著作權(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)容