Android 8.0 原始碼分析 (一) SystemServer 程式啟動

DevYK發表於2019-10-26

前言

我們熟知一般 Android 工程師都是基於 SDK 在應用層上開發,不會涉及系統原始碼,但是如果你想往底層發展,或者深入外掛化、Framework 系統層等開發工作,如果不瞭解 Android 原始碼可是不行的,那麼接下來我基於自己的理解跟學習來記錄跟 Android 開發息息相關的原始碼分析,大概從 Android 中的 SystemServer 啟動、四大元件啟動、AMS、PMS 等幾個維度來介紹,下面是我的計劃,當然在未來也有可能改變。

還沒有關注的小夥伴,可以先關注一波,系列文章會持續更新。

Android 8.0 原始碼分析 (一) SystemServer 程式啟動

Android 8.0 原始碼分析 (二) Launcher 啟動

Android 8.0 原始碼分析 (三) 應用程式程式建立到應用程式啟動的過程

Android 8.0 原始碼分析 (四) Activity 啟動

Android 8.0 原始碼分析 (五) Service 啟動

Android 8.0 原始碼分析 (六) BroadcastReceiver 啟動

Android 8.0 原始碼分析 (七) ContentProvider 啟動

Android 8.0 原始碼分析 (八) ActivityManagerService

Android 8.0 原始碼分析 (九) WindowManager

Android 8.0 原始碼分析 (十) WindowManagerService 的視窗管理

介紹

Android 中的 SystemServer 可以說是最為重要的程式也不為過,因為我們熟知的 AMS、WMS、PMS 等等都是通過它來啟動的,因此掌握 SystemServer 程式是如何啟動,它在啟動又幹了什麼,這些都是我們本章需要學習的。

原始碼分析

在分析 SystemServer 啟動原始碼之前,我們先看一下 SystemServer 啟動時序圖

K0L9ld.png

1. Zygote 開創 Java 框架層入口

根據上面時序圖我們知道是 Zygote 是 Java 框架端的入口,那麼 Zygote 是什麼呢?它有一箇中文名稱我們叫它 孵化器,顧名思義它就是為應用程式或者系統程式來建立它們對應程式的,Zygote 通過 init.rc 指令碼啟動,Zygote 啟動過程打算後面單獨寫一篇來介紹,這裡就直接跳到 JNI 層啟動 Zygote 的入口,其實就是 ZygoteInit.java 檔案,我們直接看它的 main 函式實現。

//com.android.internal.os.ZygoteInit.java
    public static void main(String argv[]) {

	    ....

        try {
          
          ...
            //是否開啟 SystemServer 標記
            boolean startSystemServer = false;
          	//服務端 Socket 名稱
            String socketName = "zygote";

          	//根據 JNI 層傳遞過來的資訊,來判斷是否啟動系統服務
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } 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]);
                }
            }
          

            /**
             * 1. 建立服務端的 Socket ,名稱為 "zygote"
             */

            zygoteServer.registerServerSocket(socketName);
           
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                /**
                 *  2. 用來預載入資源
                 */
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }

            ...

            if (startSystemServer) {
                /**
                 * 3. 啟動 SystemServer 程式
                 *
                 */
                startSystemServer(abiList, socketName, zygoteServer);
            }

            Log.i(TAG, "Accepting command socket connections");
            /**
             * 4. 等待 AMS 請求
             */
            zygoteServer.runSelectLoop(abiList);
						//清理或者關閉對應的 Socket
            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }
複製程式碼

通過上面程式碼我們可以把 ZygoteInit.main() 做的工作分為四大步

    1. 建立一個 Server 端為 ”zygote“ 名稱的 Socket,用於等待 AMS 請求 Zygote 來建立新的應用程式程式。
    1. 預處理載入類跟資源。
    1. 根據 JNI 傳遞過來的資訊來判斷是否啟動 SystemServer 程式。
    1. 等待 AMS 請求,用於建立新的應用程式程式。

1. zygoteServer.registerServerSocket(socketName);

我們首先來分析第一步具體做了什麼,看下面函式程式碼

//com.android.internal.os ZygoteServer.java

    void registerServerSocket(String socketName) {
        if (mServerSocket == null) {
            int fileDesc;
            /**
             * 1. 拿到 Socket 名稱
             */
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                /**
                 * 2. 得到 Socket 環境變數的值
                 */
                String env = System.getenv(fullSocketName);
                /**
                 * 3. 將 Socket 環境變數的值轉換為檔案描述符的引數
                 */
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                /**
                 * 4. 建立檔案描述符
                 */
                FileDescriptor fd = new FileDescriptor();
								//將 Socket 轉換出來的資訊傳遞給檔案描述符,用於獲取具體資訊
                fd.setInt$(fileDesc);
                /**
                 *5. 建立服務端 Socket
                 */
                mServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }
複製程式碼

根據上面註釋我們來總結下 registerServerSocket 函式幹了哪些事兒?

    1. 拿到拼接之後的 Socket 名稱(ANDROID_SOCKET_zygote)
    1. 通過 funSocketName Socket 名稱轉換為系統環境變數的值
    1. 將 Socket 的系統環境變數的值轉換為檔案描述符的引數
    1. 建立 FileDescriptor 檔案描述符
    1. 建立服務端 Socket 並將拿到對應的檔案描述符作為引數傳遞給服務端 Socket

最後服務端 Socket 就建立成功了,並處於等待 AMS 請求 zygote 程式來建立新的應用程式程式。

2. 啟動 SystemServer 程式

接下來請繼續回到 ZygoteInit main 函式的註釋 3 處具體實現,如下:

  //com.android.internal.os ZygoteInit.main->startSystemServer

	private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
                OsConstants.CAP_IPC_LOCK,
                OsConstants.CAP_KILL,
                OsConstants.CAP_NET_ADMIN,
                OsConstants.CAP_NET_BIND_SERVICE,
                OsConstants.CAP_NET_BROADCAST,
                OsConstants.CAP_NET_RAW,
                OsConstants.CAP_SYS_MODULE,
                OsConstants.CAP_SYS_NICE,
                OsConstants.CAP_SYS_PTRACE,
                OsConstants.CAP_SYS_TIME,
                OsConstants.CAP_SYS_TTY_CONFIG,
                OsConstants.CAP_WAKE_ALARM
        );
    
        ...
          
        /* Hardcoded command line to start the system server */
        /**
         * 1. 啟動 SystemServer 的引數
         */
        String args[] = {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "com.android.server.SystemServer", //全類名路徑
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            /**
             * 建立一個子程式,也就是 SystemServer 程式
             */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        /**
         * 如果當前程式碼執行在子程式中 ,也就是 SystemServer 程式中
         */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            //關閉 Zygote 程式建立的 Socket
            zygoteServer.closeServerSocket();
            /**
             * 處理 SystemServer 程式
             */
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }
複製程式碼

根據上面程式碼我們還是來分析下當前函式到底幹了些什麼

    1. 根據定義的 args ,作為啟動 SystemServer 程式的引數。
    1. 通過 Zygote.forkSystemServer 函式來建立 SystemServer 程式(其內部也是在 native 建立),返回程式 pid
    1. 如果 pid 為 0 那麼就表示已經執行在 SystemServer 程式中了,執行 handleSystemServerProcess 函式

handleSystemServerProcess() 具體處理 SystemServer 邏輯,在文章中第二大點中介紹。

3. zygoteServer.runSelectLoop(abiList);

SystemServer 程式啟動成功之後,會繼續回到 ZygoteInit.Main() 中執行 runSelectLoop 函式,下面看下具體實現:

//  com.android.internal.os ZygoteInit.main->runSelectLoop

    void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        /**
         * 1. 新增獲得該 Socket 的 fd 欄位的值
         */
        fds.add(mServerSocket.getFileDescriptor());
        peers.add(null);

        /**
         * 死迴圈等待 AMS 的請求
         */
        while (true) {
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            /**
             * 2. 將 fds 資訊轉存到 pollFds 陣列中。
             */
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            /**
             * 3.對 pollFds 資訊進行遍歷
             */
            for (int i = pollFds.length - 1; i >= 0; --i) {

                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                //如果 i == 0 那麼就認為 服務端 Socket 與客戶端連線上了,就是與 AMS 建立了連線
                if (i == 0) {
                    /**
                     * 4.
                     */
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    //將 ZygoteConnection 新增到 Socket 連線列表中
                    peers.add(newPeer);
                    //將 ZygoteConnection 的檔案描述符 新增到 fds 列表中
                    fds.add(newPeer.getFileDesciptor());
                } else {//如果不等於 0 ,那麼就說明 AMS 向 Zygote 傳送了一個建立應用程式的請求
                    /**
                     * 5. 呼叫 ZygoteConnection 的 runOnce 函式來建立一個新的應用程式,並在成功建立後將這個連線從 Socket 連線列表中 peers、fd 列表中關閉
                     */
                    boolean done = peers.get(i).runOnce(this);
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }
複製程式碼

通過上面程式碼我們分析該函式主要做了些什麼

    1. mServerSocket 就是我們在 registerZygoteSocket 函式中建立的伺服器端 Socket,呼叫 mServerSocket.getFileDescriptor() 函式用來獲得該 Socket 的 fd 欄位的值並新增到 fds 列表中。接下來就無限迴圈用來等待 AMS 請求 Zygote 程式建立的新的應用程式程式。
    1. 將 fds 資訊轉存到 pollFds 陣列中。
    1. 對 pollFds 資訊進行遍歷,如果 i == 0 那麼就認為 服務端 Socket 與客戶端連線上了,就是與 AMS 建立了連線,否則就說明 AMS 向 Zygote 傳送了一個建立應用程式的請求,並在成功建立後將這個連線從 Socket 連線列表中 peers、fd 列表中關閉。

小結

通過 ZygoteInit main 函式的實現,做一個小總結

    1. 通過 JNI 呼叫 ZygoteInit 的 main 函式進入 Zygote 的 Java 框架層;
    1. 通過 registerZygoteSocket 函式建立服務端 Socket,並通過 runSelectLoop 函式等待 AMS 的請求來建立新的應用程式程式。
    1. 啟動 SystemServer 程式

這一小節相當於給 SystemServer 啟動做一個鋪墊,知道在哪裡呼叫啟動,然後在具體分析。

2. SystemServer 程式處理過程

通過上一小節的第二點我們知道最後進入處理 SystemServer 是在 ZygoteInit.main() -> startSystemServer() 函式的 handleSystemServerProcess 中,那麼我們直接看該函式實現

//com.android.internal.os ZygoteInit.main

    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.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */
    }

複製程式碼

在註釋 1 處建立了 PathClassLoader 做過熱修復跟外掛化的相信對它一點不陌生,這裡不做詳細講解,可以把它理解為可以動態載入 JAR/ZIP/APK, 註釋 2 呼叫了 ZygoteInit.zygoteInit ,程式碼如下

// com.android.internal.os ZygoteInit

    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();
        /**
         * 1. 啟動 Binder 執行緒池
         */
        ZygoteInit.nativeZygoteInit();
        /**
         * 2. 進入 SystemServer 的 main 方法
         */
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
複製程式碼

註釋 1 處呼叫 ZygoteInit 的 nativeZygoteInit() 函式,其底層就是呼叫 native 層程式碼,用於啟動 Binder 執行緒池,這樣 SystemServer 就能通過 Binder 與其它程式進行通訊了。註釋 2 處作用就是反射呼叫 SystemServer main 函式。

1. Binder 執行緒池啟動

因為當前文章主要將 SystemServer 內容,對啟動 Binder 原始碼可以參考 AndroidRuntime.cpp ,app_main.cpp

啟動成功之後就可以使用 Binder 與其它程式進行通訊了。

2. 進入 SystemServer.java main() 入口

我們繼續回到 ZygoteInit.java 的 zygoteInit 中的 RuntimeInit.applicationInit 呼叫,程式碼如下

  //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);
    }

複製程式碼
    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller 
    {
        Class<?> cl;

        try {
            /**
             *1.  通過 className(com.android.server.SystemServer )反射得到SystemServer 類
             * className 通過 AMS 等其它地方傳遞過來的,並不是唯一
             */
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            /**
             * 2. 拿到 SystemServer  main 函式
             */
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ...
        } catch (SecurityException ex) {
            ...
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
           ...
        }

        /**
         * 3. 將 m 、argv 傳入 MethodAndArgsCaller,然後拋一個異常,並在 ZygoteInit.main 中進行捕獲異常
         */
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }
複製程式碼

通過上面程式碼我們知道首先通過 com.android.server.SystemServer 反射拿到 Class ,其次在通過當前獲取到的 Class 拿到它的 main 方法,最後拋了一個 Zygote.MethodAndArgsCaller(m, argv) 異常。

//com.android.internal.os Zygote.java
    public static class MethodAndArgsCaller extends Exception
            implements Runnable {
            ...
    }
複製程式碼

,通過上面程式碼我們知道,它就是繼承的 Java 異常父類 Exception ,然後是實現 Runnable 函式。這裡寫其實很有意思。這裡的異常是在 ZygoteInit.java main 函式進行捕獲,我們看程式碼實現

//com.android.internal.os ZygoteInit.java


    public static void main(String argv[]) {
				...

            if (startSystemServer) {
                /**
                 * 1. 啟動 SystemServer 程式
                 *
                 */
                startSystemServer(abiList, socketName, zygoteServer);
            }

          ....
         //2. 捕獲異常
        } catch (Zygote.MethodAndArgsCaller caller) {
      		//3. 執行 run 函式
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }
複製程式碼

通過上面程式碼最後會執行到註釋 3 處,我們看內部程式碼實現

////com.android.internal.os Zygote.java

    public static class MethodAndArgsCaller extends Exception
            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 {
                /**
                 * 1. 這裡就開始執行 SystemServer main 方法了
                 */
                mMethod.invoke(null, new Object[] { mArgs });
            } 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 ,我們知道這裡通過反射直接呼叫 SystemServer.java main() 函式,我們直接看它的 main 實現吧。

//com.android.server SystemServer.java
    /**
     * 這裡的 main 函式 主要是 zygote 通過反射呼叫
     */
    public static void main(String[] args) {
 				//呼叫內部 run 函式
        new SystemServer().run();
    }
複製程式碼
//com.android.server SystemServer.java

    private void run() {
        try {
          
           ...


            /**
             * 建立 主執行緒的訊息 Looper
             */

            Looper.prepareMainLooper();

            // Initialize native services.
            /**
             * 1. 載入動態庫 libandroid_servers .so
             */
            System.loadLibrary("android_servers");

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

            // Initialize the system context.
            /**
             * 建立系統級別的 Context
             */
            createSystemContext();

            // Create the system service manager.
            /**
             * 2. 建立 SystemServiceManager 它會對系統服務進行建立、啟動和生命週期管理
             */
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            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");
            /**
             * 3. SystemServiceManager啟動了 AMS 、PowerMS、PackageMS 等服務
             */
            startBootstrapServices();
            /**
             * 4. 啟動了 DropBoxManagerService、BatteryService、UsageStatsService 和 WebViewUpdateService
             */
            startCoreServices();
            /**
             * 5. 啟動了CameraService、AlarmManagerService、VrManagerService 等服務。
             */
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

				...

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
複製程式碼

通過上面程式碼主要做了哪些事兒,請看下面總結

    1. 建立訊息 Looper
    1. 載入動態庫 libandroid_servers .so
    1. 建立系統級別的 Context
    1. 建立 SystemServiceManager 它會對系統服務進行建立、啟動和生命週期管理
    1. 通過 SystemServiceManager 啟動 AMS 、PowerMS、PackageMS 等服務
    1. 啟動 DropBoxManagerService、BatteryService、UsageStatsService 和 WebViewUpdateService 等核心服務,他們父類都是 SystemServer
    1. 啟動 CameraService、AlarmManagerService、VrManagerService 等服務

從上面程式碼中的註釋 3,4,5 的函式中可以看出,官方把系統分為了 三種型別,分別是引導服務,核心服務和其它服務, 其中其它服務是一些非緊要和不需要立即啟動的服務。這 三種型別的服務總有 100 多個,下面列出部分系統服務及其作用。

引導服務 作用
Installer 系統安裝 APK 的一個服務類,啟動完成 Installer 服務之後才能啟動其它系統服務
ActivityManagerService 負責四大元件的啟動、切換、排程
PowerManagerService 計算系統中和 Power 相關的計算,然後決策系統應該如何反應
LightsService 管理和顯示背光 LED
DisplayManagerService 用來管理所有顯示裝置
UserManagerService 多使用者模式管理
SensorService 為系統提供各種感應器服務
PackageManagerService 用來對 APK 進行安裝、解析、刪除、解除安裝等操作
...... ......
核心服務 作用
DropBoxManagerService 用於生成和管理系統執行時的一些日誌檔案
BatteryService 管理電池相關服務
UsageStatsService 手機使用者使用每一個 APP 的頻率、使用時長
WebViewUpdateService WebView 更新服務
其它服務 作用
CameraService 攝像頭相關服務
AlarmManagerService 全域性定時器管理服務
InputManagerService 管理輸入事件
WindowManagerService 視窗管理服務
VrManagerService VR 模式管理服務
BluetoothService 藍芽管理服務
NotificationManagerService 通知管理服務
DeviceStorageMonitorService 儲存相關管理服務
LocationManagerService 定位管理服務
AudioService 音訊相關管理服務
...... ......

3. 舉例說明 ActivityManagerService 服務啟動

因為這些服務啟動邏輯都是相似的,所以這裡以啟動 ActivityManagerService 來進行舉例,程式碼如下

//com.android.server SystemServer.java
 private void startBootstrapServices() {
   
   ...
   
   //1. 呼叫 SystemServiceManager 的統一啟動服務介面 startService
    mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
   //2. AMS 與 系統服務管理類進行繫結
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
   //3. AMS 與 APK 安裝服務進行繫結 
    mActivityManagerService.setInstaller(installer);
   
   ...
 }
複製程式碼

我們先看 SystemServiceManager.startService 實現

   //com.android.server SystemServiceManager.java
		public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
       ....

          try {
            		//1. 反射例項化物件
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
              
            ....
         		//2. 
            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
複製程式碼
    public void startService(@NonNull final SystemService service) {
        // 1. 
        mServices.add(service);
        // Start it.
        long time = System.currentTimeMillis();
        try {
          	//2. 
            service.onStart();
        } catch (RuntimeException ex) {
            ...
        }
        ...
    }
複製程式碼

通過程式碼我們知道 serviceClass 就是以引數傳遞進來的 ActivityManagerService.Lifecycle.class 拿到該 class 然後反射例項化 Lifecycle 物件,最後呼叫 Lifecycle 的 onStart 函式。程式碼如下

//com.android.server.am ActivityManagerService.java

    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
          	//1. 
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
          	//2. 
            mService.start();
        }

        public ActivityManagerService getService() {
          //3. 
            return mService;
        }
    }
複製程式碼

Lifecycle 是 AMS 中的靜態內部類,繼承系統服務 SystemService , 根據上面註釋我們得到,當呼叫 serviceClass 反射例項化的時候會執行上面註釋 1,然後 service.onStart(); 對應的是 service 子類 Lifecycle 的 onStart 函式,最後 getService 就是 mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService() 該函式呼叫。

到這裡 ActivityManagerService 就被 SystemServiceManager 給例項化了。

小結

大概總結一下 SystemServer 主要做了就是啟動 三種型別 的服務,因為各個服務啟動邏輯相似,所以最後以 AMS 來舉例說明啟動流程。最後 SystemServer 程式啟動跟 其它服務啟動也講解完了,最後到了我們總結環節了。

總結

我這裡就從 Java 框架入口 ZygoteInit.main() 函式到 SystemServer 程式啟動和處理服務啟動的邏輯執行流程大概總結說明下:

    1. 建立一個 Server 端為 ”zygote“ 名稱的 Socket,用於等待 AMS 請求 Zygote 來建立新的應用程式程式。
    1. 預處理載入類跟資源。
    1. 根據 JNI 傳遞過來的資訊來判斷是否建立 SystemServer 程式。
    1. 啟動 Binder 執行緒池,與其它程式進行通訊。
    1. 進入 SystemServer.java main() 函式並建立 SystemServiceManager ,用於對各種服務的建立、啟動和生命週期的管理。
    1. 啟動各種系統服務。
    1. 等待 AMS 請求,用於建立新的應用程式程式。

AMS 和四大元件工作原理等文章會在後面陸續更新

參考

  • 《Android 進階解密》

相關文章