Zygote和System進程的啟動過程

来源:https://www.cnblogs.com/cyf1314/archive/2018/03/19/8602978.html
-Advertisement-
Play Games

##init腳本的啟動 linux內核載入完成後,運行init.rc腳本 /system/bin/app_process Zygote服務啟動的進程名 --start-system-server 表明Zygote啟動完成之後,要啟動System進程。 socket zygote stream 666 ...


##init腳本的啟動

+------------+    +-------+   +-----------+
|Linux Kernel+--> |init.rc+-> |app_process|
+------------+    +-------+   +-----------+
               create and public          
                 server socket

linux內核載入完成後,運行init.rc腳本

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server socket zygote stream 666
  • /system/bin/app_process Zygote服務啟動的進程名
  • --start-system-server 表明Zygote啟動完成之後,要啟動System進程。
  • socket zygote stream 666 在Zygote啟動時,創建一個許可權為666的socket。此socket用來請求Zygote創建新進程。socket的fd保存在名稱為“ANDROID_SOCKET_zygote”的環境變數中。

##Zygote進程的啟動過程

               create rumtime                            
  +-----------+            +----------+                  
  |app_process+----------> |ZygoteInit|                  
  +-----------+            +-----+----+                  
                                 |                       
                                 |                       
                                 | registerZygoteSocket()
                                 |                       
   +------+  startSystemServer() |                       
   |System| <-------+            |                       
   +------+   fork               | runSelectLoopMode()   
                                 |                       
                                 v   

app_process進程

/system/bin/app_process
啟動時創建了一個AppRuntime對象。通過AppRuntime對象的start方法,通過JNI調用創建了一個虛擬機實例,然後運行com.android.internal.os.ZygoteInit類的靜態main方法,傳遞true(boolean
startSystemServer)參數。

ZygoteInit類

ZygoteInit類的main方法運行時,會通過registerZygoteSocket方法創建一個供ActivityManagerService使用的server socket。然後通過調用startSystemServer方法來啟動System進程。最後通過runSelectLoopMode來等待AMS的新建進程請求。

  1. 在registerZygoteSocket方法中,通過名為ANDROID_SOCKET_zygote的環境獲取到zygote啟動時創建的socket的fd,然後以此來創建server socket。
  2. 在startSystemServer方法中,通過Zygote.forkSystemServer方法創建了一個子進程,並將其用戶和用戶組的ID設置為1000。
  3. 在runSelectLoopMode方法中,會將之前建立的server socket保存起來。然後進入一個無限迴圈,在其中通過selectReadable方法,監聽socket是否有數據可讀。有數據則說明接收到了一個請求。 selectReadable方法會返回一個整數值index。如果index為0,則說明這個是AMS發過來的連接請求。這時會與AMS建立一個新的socket連接,並包裝成ZygoteConnection對象保存起來。如果index大於0,則說明這是AMS發過來的一個創建新進程的請求。此時會取出之前保存的ZygoteConnection對象,調用其中的runOnce方法創建新進程。調用完成後將connection刪除。 這就是Zygote處理一次AMS請求的過程。

##System進程的啟動

 +                                                     
 |                                                     
 |                                                     
 v fork()                                              
 +--------------+                                      
 |System Process|                                      
 +------+-------+                                      
        |                                              
        | RuntimeInit.zygoteInit() commonInit, zygoteInitNative                                             
        | init1()  SurfaceFlinger, SensorServic...     
        |                                              
        |                                              
        | init2() +------------+                       
        +-------> |ServerThread|                       
        |         +----+-------+                       
        |              |                               
        |              | AMS, PMS, WMS...              
        |              |                               
        |              |                               
        |              |                               
        v              v           

System進程是在ZygoteInit的handleSystemServerProcess中開始啟動的。

  1. 首先,因為System進程是直接fork Zygote進程的,所以要先通過closeServerSocket方法關掉server socket。
  2. 調用RuntimeInit.zygoteInit方法進一步啟動System進程。在zygoteInit中,通過commonInit方法設置時區和鍵盤佈局等通用信息,然後通過zygoteInitNative方法啟動了一個Binder線程池。最後通過invokeStaticMain方法調用SystemServer類的靜態Main方法。
  3. SystemServer類的main通過JNI調用cpp實現的init1方法。在init1方法中,會啟動各種以C++開發的系統服務(例如SurfaceFlinger和SensorService)。然後回調ServerServer類的init2方法來啟動以Java開發的系統服務。
  4. 在init2方法中,首先會新建名為"android.server.ServerThread"的ServerThread線程,並調用其start方法。然後在該線程中啟動各種Service(例如AMS,PMS,WMS等)。啟動的方式是調用對應Service類的靜態main方法。
  5. 首先,AMS會被創建,但未註冊到ServerManager中。然後PMS被創建,AMS這時候才註冊到ServerManager中。然後到ContentService、WMS等。 註冊到ServerManager中時會制定Service的名字,其後其他進程可以通過這個名字來獲取到Binder Proxy對象,以訪問Service提供的服務。
  6. 執行到這裡,System就將系統的關鍵服務啟動起來了,這時候其他進程便可利用這些Service提供的基礎服務了。
  7. 最後會調用ActivityManagerService的systemReady方法,在該方法里會啟動系統界面以及Home程式。

##Android進程啟動

   +----------------------+       +-------+      +----------+   +----------------+   +-----------+                         
   |ActivityManagerService|       |Process|      |ZygoteInit|   |ZygoteConnection|   |RuntimeInit|                         
   +--------------+-------+       +---+---+      +-----+----+   +-----------+----+   +------+----+                         
                  |                   |                |                    |               |                              
                  |                   |                |                    |               |                              
 startProcessLocked()                 |                |                    |               |                              
+---------------> |                   |                |                    |               |                              
                  |  start()          |                |                    |               |                              
                  |  "android.app.ActivityThread"      |                    |               |                              
                  +-----------------> |                |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   |openZygoteSocketIfNeeded()           |               |                              
                  |                   +------+         |                    |               |                              
                  |                   |      |         |                    |               |                              
                  |                   | <----+         |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   |sZygoteWriter.write(arg)             |               |                              
                  |                   +------+         |                    |               |                              
                  |                   |      |         |                    |               |                              
                  |                   |      |         |                    |               |                              
                  |                   | <----+         |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   +--------------> |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   |                |runSelectLoopMode() |               |                              
                  |                   |                +-----------------+  |               |                              
                  |                   |                |                 |  |               |                              
                  |                   |                | <---------------+  |               |                              
                  |                   |                |   acceptCommandPeer()              |                              
                  |                   |                |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   |                |  runOnce()         |               |                              
                  |                   |                +------------------> |               |                              
                  |                   |                |                    |forkAndSpecialize()                           
                  |                   |                |                    +-------------+ |                              
                  |                   |                |                    |             | |                              
                  |                   |                |                    | <-----------+ |                              
                  |                   |                |                    |  handleChildProc()                           
                  |                   |                |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   |                |                    |               |                              
                  |                   |                |                    | zygoteInit()  |                              
                  |                   |                |                    +-------------> |                              
                  |                   |                |                    |               |                              
                  |                   |                |                    |               |in^okeStaticMain()            
                  |                   |                |                    |               +---------------->             
                  |                   |                |                    |               |("android.app.ActivityThread")
                  |                   |                |                    |               |                              
                  |                   |                |                    |               |                              
                  +                   +                +                    +               +                            
  • AMS向Zygote發起請求(通過之前保存的socket),攜帶各種參數,包括“android.app.ActivityThread”。
  • Zygote進程fork自己,然後在新Zygote進程中調用RuntimeInit.zygoteInit方法進行一系列的初始化(commonInit、Binder線程池初始化等)。
  • 新Zygote進程中調用ActivityThread的main函數,並啟動消息迴圈。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、問題概述 在錯誤日誌中看到非常多的alwayson群集只讀連接錯誤,錯誤信息的描述為“目標資料庫位於可用性組,當前不允許通過read only連接”。錯誤日誌如下: 當前的業務系統使用監聽ip對資料庫進行連接,使用了ReadOnly和ReadWrite進行讀寫自動路由。當前alwayson的配置 ...
  • alter TABLE uimsUserBelongGroup add PRIMARY key(rsMainkeyid); --設置主鍵 alter table uimsUserBelongGroup MODIFY rsMainkeyid bigint auto_increment; --設置自增長 ...
  • 前幾天編寫一個存儲過程,需要訪問遠程資料庫的欄位,於是建立一個dbLink並建了同義詞: 這裡之所以用orcl@bdc為dblink的名稱是為了設置global_names=true。 然後新建一個存儲過程調用該同義詞: v_result mtb.sid%type; 調用後發現提示:錯誤:PLS-0 ...
  • 主從伺服器 1. 將讀操作和寫操作分離到不同的資料庫上,避免主伺服器出現性能瓶頸; 2. 主伺服器進行寫操作時,不影響查詢應用伺服器的查詢性能,降低阻塞,提高併發; 3. 數據擁有多個容災副本,提高數據安全性,同時當主伺服器故障時,可立即切換到其他伺服器,提高系統可用性; 讀寫分離的基本原理就是讓主 ...
  • -(void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; } 在這裡你需要釋放掉所有占用了很大記憶體的對象,如果你忽略了這個警告,應用有可能直接閃退。iOS設備沒有虛擬記憶體或者交換分區,記憶體用完了就是真的用完了,沒有任何迴旋的餘地 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • Android #Android開發環境搭建 1.下載:Google在國服的官網 https://developer.android.google.cn/index.html 1.點擊首頁 “ 獲取 Android Studio” 2.跳轉以後等待網頁載入完(左上角顯示X則是未載入完)再點擊綠色的“ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...