安卓系統應用啓動流程分析

隨着移動開發的興起,安卓系統的重要性愈加突顯。本文簡要介紹安卓系統上應用啓動流程,對於應用開發、系統定製以及性能優化人員來說,熟悉應用啓動流程會使得在今後的工作中更加得心應手,做到知其然,知其所以然。本文主要面向開發人員,假定讀者已有一定的安卓基礎。

本文以安卓P版本爲基礎,不同安卓版本上應用啓動流程略有差異,但核心邏輯仍然一致。

安卓上應用啓動的幾種形式

冷啓動

這種方式應用需要完成完整的啓動過程,即創建進程、初始化資源及顯示應用界面,相比於另外兩種啓動模式,應用冷啓動耗時最長。

熱啓動

這種方式下應用進程已經啓動,通常只需將要顯示的activity帶到前臺即可,所以在該模式下應用可以較快速啓動。

溫啓動

這種方式需要完成部分冷啓動過程,比如進程已經創建,但要重新執行activity的onCreate()來創建要顯示的activity,這種模式下的啓動時間介於以上兩種之間。

本文主要介紹冷啓動的執行流程。

應用啓動相關的一些基本概念

zygote

該進程是安卓上所有應用進程的父進程,在開機過程中由系統啓動並保持運行狀態。由於現在的安卓平臺大部分同時支持32位和64位應用,zygote也分爲32位和64位兩個版本,其原理相同,在本文中不做區分。

system_server

安卓上的系統服務進程,絕大部分主要系統服務都駐留在該進程內,包括下文中介紹的AMS、WMS、PMS等。system_server由zygote在啓動進程中分裂而來(即也是zygote的子進程),然後持續運行。

AMS

Activity Manager Service,是安卓上的一個核心服務,負責管理應用各個組件,所有應用在其生命週期內均需和AMS打交道。該服務駐留在system_server進程內。 

WMS

Window Manager Service,是安卓上的窗口管理服務,負責處理應用的界面顯示相關的請求。該服務駐留在system_server進程內。

PMS

Package Manager Service,是安卓上的包管理服務,負責處理應用的安裝、缷載等。該服務駐留在system_server進程內。

應用冷啓動的任務序列

在冷啓動時,系統首先有三個任務:

1. 在AMS端分配應用資源;

2. 顯示應用的空白啓動窗口;

3. 創建應用進程;

在應用進程啓動後,應用進程會負責啓動的後續階段:

1. 創建應用對象;

2. 啓動主線程;

3. 創建主activity並完成繪製及顯示;

應用進程完成第一幀繪製後,系統會將空白窗口替換爲應用的畫面,此時,用戶可以開始使用應用。

典型的冷啓動場景及流程

接下來,我們以一個典型場景,即從桌面點擊應用圖標啓動應用這一過程,來介紹應用啓動流程。其它應用啓動場景,比如從命令行啓動,或者從A應用啓動B應用,與本場景大同小異,本文中不再另做說明。

先看下簡要的流程圖:

如上圖所示,當用戶點擊桌面上應用圖標後,Launcher進程會將應用信息發送給AMS,由於這時應用進程還沒有啓動,所以需要先創建應用進程,AMS收到請求後會發送命令給zygote進程要求創建目標應用進程,當目標進程啓動後,會將自身的遠程handle註冊給AMS,這樣AMS就可以控制應用進程去執行接下來的一系列啓動操作。

接下來,我們對這一過程做下詳細說明。

1. 用戶點擊應用圖標後,launcher進程向system_server進程發消息請求啓動應用進程,即launcher通過startActivity()向AMS發送請求啓動對應的activity,核心代碼如下:

frameworks/base/core/java/android/app/Activity.java

其中,參數intent包含了要啓動的目標應用的信息。

以上代碼最終會調用AMS內部的startActivity(),由於Launcher和AMS分屬不同進程,這一過程通過binder通信。

2. system_server進程收到請求後,通過其內部邏輯,即AMS收到startActivity()調用後,會進行必要的權限檢查,創建activity的內部表示即ActivityRecord對象,並顯示一個空白的窗口。

核心代碼如下:

frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java

由於應用冷啓動時進程不存在,AMS會通過zygote創建應用進程。

核心代碼如下:

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

具體流程如下:

在非冷啓動的情況,即如果應用進程已經啓動完成,則可以直接進入啓動activity的邏輯,代碼如下:

在冷啓動的startProcessLocked()調用過程中,有一個參數需要特別注意,即 ”entryPoint”,這個參數表示zygote分裂出的應用進程的入口,其定義爲:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

也就是說,ActivityThread是應用程序的入口。

3. 當應用進程啓動後,會進入ActivityThread的main()方法執行應用端邏輯;

核心代碼如下:

frameworks/base/core/java/android/app/ActivityThread.java

創建ActivityThread對象時,會同時創建應用進程的表示對象,即該應用的handle,代碼如下:

frameworks/base/core/java/android/app/ActivityThread.java

同時要特別注意應用進程的“attach”操作,這一操作會將應用進程自身的遠程handle即mAppThread註冊給AMS,這樣AMS就可以和應用通信,通知應用執行後續的操作,啓動相應的activity;

核心代碼如下:

frameworks/base/core/java/android/app/ActivityThread.java

4. 現在應用進程已經啓動,並且已與AMS建立關聯,AMS會繼續執行啓動應用的第一個activity的邏輯;

核心代碼如下:

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

其中,realStartActivityLocked()會通知應用啓動相應activity,邏輯如下:

5. 應用進程收到 ”launch”及”resume” 命令後,就會創建相應的activity對象以及關聯的窗口對象等資源,並調用activity的生命週期回調函數完成activity的顯示;到此,應用進程的第一個activity就創建完成了;

核心代碼如下:

frameworks/base/core/java/android/app/ActivityThread.java

初始化圖形資源及與WMS的連接:

創建activity對象:

初始化activity實例:

調用activity的onCreate()函數:

接下來會繼續activity的其它生命週期回調函數並將activity顯示出來,至此,一個應用的首個activity即完成了啓動。

總結

本文簡要說明了安卓平臺上應用啓動的流程,通過本篇介紹,希望讀者能理清應用啓動的大致脈絡,對應用啓動過程有一個基本的理解。

參考資料

[1]http://androidxref.com/

[2]https://developer.android.com/topic/performance/vitals/launch-time

推薦閱讀:

專輯|Linux文章彙總

專輯|程序人生

專輯|C語言

嵌入式Linux

微信掃描二維碼,關注我的公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章