在前面多篇文章中,都有提到ActivityManagerService,它是在系統啟動時加載的一個服務線程,運行於system_server進程中,主要負責管理系統中的Activity和Service,那麼,ActivityManagerService是怎麼管理和維護這些Activity和Service的呢?這裡的Service,指的是Activity應用裡的Service。在看本篇文章之間,請先參閱《Android
進階 - 進階啟動分析》,《Android 進階 - Activity應用啟動分析》,《Android 進階 -
Activity服務啟動分析》幾篇文章,這樣感覺會更直觀。
1. 接口圖
由於ActivityManagerService服務與Activity應用不在同一進程,之間的通訊都是采用Binder通訊,為了更好的理解ActivityManagerService是如何管理Activity和Service,又是如何與Activity和Service通訊的,我們先來看看組件圖:
由上圖可看出,無論是Activity應用還是Activity Service都是運行在ActivityThread裡,左邊是服務調用端,右邊是服務的服務端,中間為ActivityManagerService服務端。
引出的幾個接口都是基於Binder的遠程通訊進接口,有了這幾個接口,Activity應用就可以和ActivityManagerService(以下簡稱ams)相互通訊了。
2. 通信流程簡介
2.1 Activity調用ams服務
ams屬於系統服務,IActivityManager可以通過ServiceManager.getSystemService("activity");獲取,詳見ActivityManagerNative.getDefault()的代碼。這個調用過程相對簡單,凡是遇到ActivityManagerNative.getDefault().xxx()的代碼,都是走的IActivityManager的遠程接口,調用ams中的對應的接口。
2.2 ams調用Activity
在Activity應用啟動之後,會創建ApplicationThread服務端,在調用ams的attachApplication接口時,會傳入ApplicationThread對象,經由Binder進入ams後,此接口變為IApplicationThread遠程接口,ams會將此變量與ams內部保存的app綁定在一起,建立起綁定之後,ams就可以通過app.thread反向調用Activity應用中提供的服務。
2.3 ams通知Activity服務
當Activity服務綁定成功之後,ams通過IServiceConnection遠程接口,通知Activity客戶端,服務已經綁定,並且會傳回IXXXService遠程接口對象,並經由ServiceConnect.onServiceConnected傳給Activity。IServiceConnection是Activity客戶端在bindService時,生成的一個LoadedApk.ServiceDispatch.InnerConnection對象,經由Binder傳入到ams後,變為IServiceConnection遠程接口,並保存ams的ActivityRecord列表中。
同理,當服務斷開綁定後,也是通過IServiceConnection,通知Activity客戶端,連接已經斷開。
2.4 Activity應用調用Activity服務
當Activity應用接收到ServiceConnection.onServiceConnected事件後,但拿到XXXService服務端的遠程接口IXXXService,Activity應用可以通過此遠程接口,訪問Activity服務中提供的服務。
3. ams的管理功能
從前面的介紹可以看出,ams就是Android系統中各類Activity和Service的通訊橋梁和大管家,ams中保存有所有的進程記錄,Activity記錄,Service記錄等。
在ams裡,有如下成員變量:
mPidsSelfLocked:這是一個根據進程id(pid)保存的ProcessRecord數組,當有新進程創建時,會往mPidsSelfLocked裡put一個進程記錄ProcessRecord,並與pid關聯,這樣,以後可以通過pid來從此數組中獲取進程的詳細信息。
mProcessNames:這是根據進程名稱保存的ProcessRecord數組,當新進程創建時,會往mProcessNames裡put一個進程記錄ProcessRecord,並與進程名稱關聯,以後可以通過進程名稱來獲取進程信息。mIsolatedProcesses:隔離的進程列表,isolated進程是一個特殊進程,沒有用戶權限,只能API接口與其通訊。在Android Service中,如果isolated=true,即表示該服務為隔離的進程。
mProcessesOnHold:暫時掛起的進程列表,這些進程因嘗試在系統啟動(system ready)完成之前啟動,而被暫時掛起,當系統啟動完成之後,會啟動該列表中的進程。
mPersistentStartingProcesses:持久化核心進程列表,這些進程免受out-of-memory killer的影響,不會被kill掉。當一個應用的android:persistent="true"時,該應用就升級為核心進程。
mRemovedProcesses:被移除的進程列表。
mLruProcesses:當前正在運行的進程信息列表。上面的進程信息列表,都不一定表示列表時的進程都在運行,此成員可以得出正在運行的進程列表。
mProcessesToGc:當前已被通知清理內存的進程列表,和Android內存回收機制相關。
mPendingPssProcesses:正在請求獲取PSS Data的進程列表,和Android內存機制相關。
mHomeProcess: 主屏幕應用進程
mPreviousProcess:上一個進程
上面是與進程信息管理相關的成員,最常用到的就是mPidsSelfLocked和mProcessNames。這些信息都與ProcessRecord相關,ProcessRecord即進程記錄,記錄著一個進程的詳細信息。ProcessRecord的成員非常多,這裡挑選幾個關鍵的成員說明:
pid:進程IDthread:與進程相關聯的應用遠程IBinder接口(IApplicationThread),是ams與應用進程通訊的橋梁,ams可以通過此接口訪問應用的服務功能。此接口在應用進程創建之後,通過ams.attachApplication,保存到ams的ProcessRecord中。activities:應用的Activity列表,所有此應用裡啟動的Activity,都保存在該列表中,列表中的對象為ActivityRecord。
services:應用的Service列表,所有 此應用裡啟動的Service,都保存在該列表中,列表中的對象為ServcieRecord。executingServices:正在運行的服務列表,列表中的對象為ServiceRecord。connections:所有此應用保持的連接(包含:IServiceConnection)列表,這個連接列表是Activity 客戶端綁定服務時創建的,當服務綁定成功之後,要通過IServiceConnection,將onServiceConnected事件發送至Activity客戶端。receivers:此應用所有注冊的receiver列表,列表中的對象為ReceiverList。
pubProviders:此應用所有發布的ContentProvider列表。
conProviders:此應用正在使用的ContentProvider列表。pkgList:此應用正在運行的package列表。
上面只簡單介紹一些常用的信息,其他信息請自行研究源碼。
4. ams的作用
簡言之,ams作用就是各應用與服務之間的通信橋梁,由於Android屏蔽了進程概念,無論是應用內部的Activity或Servcie,還是另一應用的Activity或Service,啟動都要經過ams。按道理,我在應用內部Start一個Activity,直接new出來就行了,但在Android裡,不能這樣做,必須繞個彎,通過ams,再由ams進入應用本身來啟動。這樣一來,所有應用進程裡的所有Activity和Service,都保存在ams裡,ams成了一個真正大管家。
應用調用ams,采用ams提供的IActivityManager遠程Binder接口。而ams反調應用,則是應用提供的IApplicationThread遠程Binder接口。當服務綁定之後,ams反調應用提供的IServcieConnection遠程Binder接口,來通知應用服務已經連接。IApplicationThread和IServiceConnection都不是Android Service的接口,由此可以看出,Binder是進程間通訊用的,並不一定是服務程序獨有的,這將在後面的文章詳細介紹。