Android系統程式Zygote啟動過程的原始碼分析(3)
Step 5. ZygoteInit.startSystemServer
這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:
- public class ZygoteInit {
- ......
- private static boolean startSystemServer()
- throws MethodAndArgsCaller, RuntimeException {
- /* Hardcoded command line to start the system server */
- String args[] = {
- "--setuid=1000",
- "--setgid=1000",
- "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
- "--capabilities=130104352,130104352",
- "--runtime-init",
- "--nice-name=system_server",
- "com.android.server.SystemServer",
- };
- ZygoteConnection.Arguments parsedArgs = null;
- int pid;
- try {
- parsedArgs = new ZygoteConnection.Arguments(args);
- ......
- /* Request to fork the system server process */
- pid = Zygote.forkSystemServer(
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, debugFlags, null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities);
- } catch (IllegalArgumentException ex) {
- ......
- }
- /* For child process */
- if (pid == 0) {
- handleSystemServerProcess(parsedArgs);
- }
- return true;
- }
- ......
- }
這裡我們可以看到,Zygote程式通過Zygote.forkSystemServer函式來建立一個新的程式來啟動SystemServer元件,返回值pid等0的地方就是新的程式要執行的路徑,即新建立的程式會執行handleSystemServerProcess函式。
Step 6. ZygoteInit.handleSystemServerProcess
這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:
- 這裡我們可以看到,Zygote程式通過Zygote.forkSystemServer函式來建立一個新的程式來啟動SystemServer元件,返回值pid等0的地方就是新的程式要執行的路徑,即新建立的程式會執行handleSystemServerProcess函式。
- Step 6. ZygoteInit.handleSystemServerProcess
- 這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:
由於由Zygote程式建立的子程式會繼承Zygote程式在前面Step 4中建立的Socket檔案描述符,而這裡的子程式又不會用到它,因此,這裡就呼叫closeServerSocket函式來關閉它。這個函式接著呼叫RuntimeInit.zygoteInit函式來進一步執行啟動SystemServer元件的操作。
Step 7. RuntimeInit.zygoteInit
這個函式定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java檔案中:
- public class RuntimeInit {
- ......
- public static final void zygoteInit(String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- ......
- zygoteInitNative();
- ......
- // Remaining arguments are passed to the start class's static main
- String startClass = argv[curArg++];
- String[] startArgs = new String[argv.length - curArg];
- System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
- invokeStaticMain(startClass, startArgs);
- }
- ......
- }
這個函式會執行兩個操作,一個是呼叫zygoteInitNative函式來執行一個Binder程式間通訊機制的初始化工作,這個工作完成之後,這個程式中的Binder物件就可以方便地進行程式間通訊了,另一個是呼叫上面Step 5傳進來的com.android.server.SystemServer類的main函式。
Step 8. RuntimeInit.zygoteInitNative
這個函式定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java檔案中:
- public class RuntimeInit {
- ......
- public static final native void zygoteInitNative();
- ......
- }
這裡可以看出,函式zygoteInitNative是一個Native函式,實現在frameworks/base/core/jni/AndroidRuntime.cpp檔案中,這裡我們就不再細看了,具體可以參考Android應用程式程式啟動過程的原始碼分析一文的Step 9,完成這一步後,這個程式的Binder程式間通訊機制基礎設施就準備好了。
回到Step 7中的RuntimeInit.zygoteInitNative函式,下一步它就要執行com.android.server.SystemServer類的main函式了。
Step 9. SystemServer.main
這個函式定義在frameworks/base/services/java/com/android/server/SystemServer.java檔案中:
- public class SystemServer
- {
- ......
- native public static void init1(String[] args);
- ......
- public static void main(String[] args) {
- ......
- init1(args);
- ......
- }
- public static final void init2() {
- Slog.i(TAG, "Entered the Android system server!");
- Thread thr = new ServerThread();
- thr.setName("android.server.ServerThread");
- thr.start();
- }
- ......
- }
這裡的main函式首先會執行JNI方法init1,然後init1會呼叫這裡的init2函式,在init2函式裡面,會建立一個ServerThread執行緒物件來執行一些系統關鍵服務的啟動操作,例如我們在前面兩篇文章Android應用程式安裝過程原始碼分析和Android系統預設Home應用程式(Launcher)的啟動過程原始碼分析中提到的PackageManagerService和ActivityManagerService。
這一步的具體執行過程可以參考Android應用程式安裝過程原始碼分析一文,這裡就不再詳述了。
這裡執行完成後,層層返回,最後回到上面的Step 3中的ZygoteInit.main函式中,接下來它就要呼叫runSelectLoopMode函式進入一個無限迴圈在前面Step 4中建立的socket介面上等待ActivityManagerService請求建立新的應用程式程式了。
Step 10. ZygoteInit.runSelectLoopMode
這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中:
- public class ZygoteInit {
- ......
- private static void runSelectLoopMode() throws MethodAndArgsCaller {
- ArrayList<FileDescriptor> fds = new ArrayList();
- ArrayList<ZygoteConnection> peers = new ArrayList();
- FileDescriptor[] fdArray = new FileDescriptor[4];
- fds.add(sServerSocket.getFileDescriptor());
- peers.add(null);
- int loopCount = GC_LOOP_COUNT;
- while (true) {
- int index;
- ......
- try {
- fdArray = fds.toArray(fdArray);
- index = selectReadable(fdArray);
- } catch (IOException ex) {
- throw new RuntimeException("Error in select()", ex);
- }
- if (index < 0) {
- throw new RuntimeException("Error in select()");
- } else if (index == 0) {
- ZygoteConnection newPeer = acceptCommandPeer();
- peers.add(newPeer);
- fds.add(newPeer.getFileDesciptor());
- } else {
- boolean done;
- done = peers.get(index).runOnce();
- if (done) {
- peers.remove(index);
- fds.remove(index);
- }
- }
- }
- }
- ......
- }
這個函式我們已經在Android應用程式程式啟動過程的原始碼分析一文的Step 5中分析過了,這就是在等待ActivityManagerService來連線這個Socket,然後呼叫ZygoteConnection.runOnce函式來建立新的應用程式,有興趣的讀者可以參考Android應用程式程式啟動過程的原始碼分析這篇文章,這裡就不再詳述了。
這樣,Zygote程式就啟動完成了,學習到這裡,我們終於都對Android系統中的程式有了一個深刻的認識了,這裡總結一下:
1. 系統啟動時init程式會建立Zygote程式,Zygote程式負責後續Android應用程式框架層的其它程式的建立和啟動工作。
2. Zygote程式會首先建立一個SystemServer程式,SystemServer程式負責啟動系統的關鍵服務,如包管理服務PackageManagerService和應用程式元件管理服務ActivityManagerService。
3. 當我們需要啟動一個Android應用程式時,ActivityManagerService會通過Socket程式間通訊機制,通知Zygote程式為這個應用程式建立一個新的程式。
相關文章
- Android系統原始碼分析–Zygote和SystemServer啟動過程Android原始碼GoServer
- Android系統原始碼分析--Activity啟動過程Android原始碼
- Androd 系統原始碼-3:應用啟動過程的原始碼分析原始碼
- Android系統啟動流程(二)解析Zygote程式AndroidGo
- Android 系統原始碼-1:Android 系統啟動流程原始碼分析Android原始碼
- React Native Android 原始碼分析之啟動過程React NativeAndroid原始碼
- Android系統原始碼分析--Service啟動流程Android原始碼
- Android系統原始碼分析–Service啟動流程Android原始碼
- Spring啟動過程——原始碼分析Spring原始碼
- Android 8.0 原始碼分析 (三) 應用程式程式建立到應用程式啟動的過程Android原始碼
- Netty NioEventLoop 啟動過程原始碼分析NettyOOP原始碼
- Spring Boot原始碼分析-啟動過程Spring Boot原始碼
- Spring MVC 啟動過程原始碼分析SpringMVC原始碼
- 《10分鐘剖析》系統啟動3——Zygote的使命Go
- Spring啟動過程——原始碼分析(finishBeanFactoryInitialization(beanFactory))Spring原始碼Bean
- [譯]Android系統是如何啟動應用程式的?從Zygote到Activity的onCreate()AndroidGo
- Android系統啟動流程(四)Launcher啟動過程與系統啟動流程Android
- Spring啟動過程原始碼分析基本概念Spring原始碼
- Android 8.0 原始碼分析 (一) SystemServer 程式啟動Android原始碼Server
- 精盡Spring Boot原始碼分析 - SpringApplication 啟動類的啟動過程Spring Boot原始碼APP
- Hive原始碼分析(1)——HiveServer2啟動過程Hive原始碼Server
- 走近原始碼:Redis的啟動過程原始碼Redis
- 《10分鐘剖析》系統啟動2——啟動zygoteGo
- 圖解 Android 系列(一)揭祕 Android 系統啟動過程圖解Android
- 【原始碼】Redis Server啟動過程原始碼RedisServer
- Android Activity啟動流程原始碼分析Android原始碼
- Android原始碼分析:Activity啟動流程Android原始碼
- Netty服務端啟動過程相關原始碼分析Netty服務端原始碼
- [原始碼分析] 訊息佇列 Kombu 之 啟動過程原始碼佇列
- 從原始碼看微信小程式啟動過程原始碼微信小程式
- 【Android】【init】解析init程式啟動過程Android
- 理解 Android 程式啟動之全過程Android
- Linux系統啟動過程Linux
- 作業系統啟動的過程作業系統
- 原始碼|HDFS之NameNode:啟動過程原始碼
- 以太坊啟動過程原始碼解析原始碼
- SpringMVC原始碼解析(1)-啟動過程SpringMVC原始碼
- Android 原始碼分析(一)專案構建過程Android原始碼
- Redis核心原理與實踐--Redis啟動過程原始碼分析Redis原始碼