1. 程式人生 > >android應用程式啟動詳情之程序相關

android應用程式啟動詳情之程序相關



       當某個應用元件啟動且該應用沒有執行其他任何元件時,Android 系統會使用單個執行執行緒為應用啟動新的 Linux 程序。
預設情況下,同一應用的所有元件在相同的程序和執行緒(稱為“主”執行緒)中執行。 如果某個應用元件啟動且該應用已存在程序(因為存在該應用的其他元件),則該元件會在此程序內啟動並使用相同的執行執行緒。
也可以在AndroidManifest.xml中配置Android:process屬性,使得元件執行在其他的程序中

1、兩個重要的程序:
•Zygote程序:是Android系統的首個Java程序,Zygote是所有Java程序的父程序,包括 system_server程序以及所有的App程序都是Zygote的子程序,注意這裡說的是子程序,而非子執行緒。
•system_server程序:是用於管理整個Java framework層,包含ActivityManager,PowerManager等各種系統服務;

•serviceManager程序:  是由init孵化而來的,是整個Binder架構(IPC)的大管家,所有大大小小的service都需要先請示servicemanager,這個在啟動一個應用時需要使用binder進行程序間通訊,通知到system_server去。


2、Zygote程序由Init程序啟動:
    在Linux系統中,所有的程序都是init程序的子孫程序,也就是說,所有的程序都是直接或者間接地由init程序fork出來的。Zygote程序也是在系統啟動的過程,由init程序建立的。
    1).系統啟動時init程序會建立Zygote程序,Zygote程序負責後續Android應用程式框架層的其它程序的建立和啟動工作。
    2). Zygote程序會首先建立一個SystemServer程序,SystemServer程序負責啟動系統的關鍵服務,如包管理服務PackageManagerService和應用程式元件管理服務ActivityManagerService。
    3).當我們需要啟動一個Android應用程式時,ActivityManagerService會通過Socket程序間通訊機制,通知Zygote程序為這個應用程式建立一個新的程序。

3、Android應用程式程序啟動過程
    1).App發起程序:當從桌面啟動應用,則發起程序便是Launcher所在程序;當從某App內啟動遠端程序,則傳送程序便是該App所在程序。發起程序先通過binder傳送訊息給system_server程序;
    2).system_server程序:呼叫Process.start()方法,通過socket向zygote程序傳送建立新程序的請求;
    3).zygote程序:在執行ZygoteInit.main()後便進入runSelectLoop()迴圈體內,當有客戶端連線時便會執行ZygoteConnection.runOnce()方法,再經過層層呼叫後fork出新的應用程序;

    4).新程序:執行handleChildProc方法,最後呼叫ActivityThread.main()方法。

4、虛擬機器、程序、應用和TASK之間的關係

      一個虛擬機器只能跑一個程序(虛擬機器就是給程序建立一個單獨的執行空間),

      一個程序裡可以跑多個應用(通過程序通訊呼叫到其他應用來為其服務),
      一個應用也可以跑在多個程序中(對等的當前應用會被其他程序呼叫)。

      在Android中TASK概念是從使用者角度出發,為了完成某一個功能時,可能會同時呼叫不同的程序來實現。 比如給XXX傳送一條彩信,其中包括新增一張拍照,新增一個聯絡人等等。需要在簡訊應用中呼叫到其他的程序(camera,contact)。 所有這些操作統稱為一個task。可以體現在recent task中,在上面這種例子下只顯示一個message應用,其中用到的camera和contact程序不會顯示出來

5、Android程序間的優先順序

      在Android執行執行過程中,當出現記憶體不足的情況下系統會根據程序之前的優先順序從低到高依次Kill 程序,從而保證記憶體空間。

1)前臺程序: 使用者當前操作所必需的程序。如果一個程序滿足以下任一條件,即視為前臺程序:
  - 託管使用者正在互動的 Activity(已呼叫 Activity 的 onResume() 方法)
  - 託管某個 Service,後者繫結到使用者正在互動的 Activity
  - 託管正在“前臺”執行的 Service(服務已呼叫 startForeground())
  - 託管正執行一個生命週期回撥的 Service(onCreate()、onStart() 或 onDestroy())
  - 託管正執行其 onReceive() 方法的 BroadcastReceiver
通常,在任意給定時間前臺程序都為數不多。只有在記憶體不足以支援它們同時繼續執行這一萬不得已的情況下,系統才會終止它們。 此時,裝置往往已達到記憶體分頁狀態,因此需要終止一些前臺程序來確保使用者介面正常響應。

2).可見程序: 沒有任何前臺元件、但仍會影響使用者在螢幕上所見內容的程序。 如果一個程序滿足以下任一條件,即視為可見程序:
  - 託管不在前臺、但仍對使用者可見的 Activity(已呼叫其 onPause() 方法)。例如,如果前臺 Activity 啟動了一個對話方塊,允許在其後顯示上一 Activity,則有可能會發生這種情況。
  - 託管繫結到可見(或前臺)Activity 的 Service。
可見程序被視為是極其重要的程序,除非為了維持所有前臺程序同時執行而必須終止,否則系統不會終止這些程序。
3).服務程序
  正在執行已使用 startService() 方法啟動的服務且不屬於上述兩個更高類別程序的程序。儘管服務程序與使用者所見內容沒有直接關聯,但是它們通常在執行一些使用者關心的操作(例如,在後臺播放音樂或從網路下載資料)。因此,除非記憶體不足以維持所有前臺程序和可見程序同時執行,否則系統會讓服務程序保持執行狀態。
4).後臺程序
  包含目前對使用者不可見的 Activity 的程序(已呼叫 Activity 的 onStop() 方法)。這些程序對使用者體驗沒有直接影響,系統可能隨時終止它們,以回收記憶體供前臺程序、可見程序或服務程序使用。 通常會有很多後臺程序在執行,因此它們會儲存在 LRU (最近最少使用)列表中,以確保包含使用者最近檢視的 Activity 的程序最後一個被終止。如果某個 Activity 正確實現了生命週期方法,並儲存了其當前狀態,則終止其程序不會對使用者體驗產生明顯影響,因為當用戶導航回該 Activity 時,Activity 會恢復其所有可見狀態。 有關儲存和恢復狀態的資訊,請參閱 Activity文件。
5).空程序
  不含任何活動應用元件的程序。保留這種程序的的唯一目的是用作快取,以縮短下次在其中執行元件所需的啟動時間。 為使總體系統資源在程序快取和底層核心快取之間保持平衡,系統往往會終止這些程序。

參考資料:

程序和執行緒 ;