frameworks/base/services/core/java/com/android/server/am/
- ActivityManagerService.java
- ProcessRecord
- ActivityStackSupervisor.java
- ActivityStack.java
- ActiveServices
- BroadcastQueue
一. 引言
Android系統(tǒng)內(nèi)部非常復(fù)雜,經(jīng)層層封裝后,app只需要簡單的幾行代碼便可完成任一組件的啟動/結(jié)束、 生命周期的操作。然而每一次看似簡單的操作,背后所有的復(fù)雜工作都是交由系統(tǒng)來完成。
組件啟動后,首先需要依賴進(jìn)程,那么就需要先創(chuàng)建進(jìn)程,系統(tǒng)需要記錄每個進(jìn)程,這便產(chǎn)生了ProcessRecord。 Android中,對于進(jìn)程的概念被弱化,通過抽象后的四大組件。讓開發(fā)者幾乎感受不到進(jìn)程的存在。 當(dāng)應(yīng)用退出時,進(jìn)程也并非馬上退出,而是成為cache/empty進(jìn)程,下次該應(yīng)用再啟動的時候,可以不用 再創(chuàng)建進(jìn)程直接初始化組件即可,提高啟動速度。先來說一說進(jìn)程。
二. 進(jìn)程管理
Android系統(tǒng)中用于描述進(jìn)程的數(shù)據(jù)結(jié)構(gòu)是ProcessRecord對象,AMS便是管理進(jìn)程的核心模塊。四大組件 (Activity,Service, BroadcastReceiver, ContentProvider)定義在AndroidManifest.xml文件, 每一項都可以用屬性android:process指定所運行的進(jìn)程。同一個app可以運行在通過一個進(jìn)程,也可以運行在多個進(jìn)程, 甚至多個app可以共享同一個進(jìn)程。例如:AndroidManifest.xml中定義Service:
<service android:name =".GityuanService" android:process =":remote" >
<intent-filter>
<action android:name ="com.action.gityuan" />
</intent-filter>
</service>
GityuanService這個服務(wù)運行在remote進(jìn)程。
2.1 進(jìn)程關(guān)系圖
以一幅圖來展示AMS管理進(jìn)程的相關(guān)成員變量以及ProcessRecord對象:
[圖片上傳中...(image-dc86ea-1513257973227-2)]
2.2 進(jìn)程與AMS的關(guān)聯(lián)
這里只介紹AMS的進(jìn)程相關(guān)的成員變量:
-
mProcessNames:數(shù)據(jù)類型為ProcessMap<processrecord style="box-sizing: border-box; user-select: text !important;">,以進(jìn)程名和userId為key來記錄ProcessRecord;</processrecord>
- 添加進(jìn)程,addProcessNameLocked()
- 刪除進(jìn)程,removeProcessNameLocked()
-
mPidsSelfLocked: 數(shù)據(jù)類型為SparseArray<processrecord style="box-sizing: border-box; user-select: text !important;">,以進(jìn)程pid為key來記錄ProcessRecord;</processrecord>
- startProcessLocked(),移除已存在進(jìn)程,增加新創(chuàng)建進(jìn)程pid信息;
- removeProcessLocked,processStartTimedOutLocked,cleanUpApplicationRecordLocked移除進(jìn)程;
-
mLruProcesses:數(shù)據(jù)類型為ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">,以進(jìn)程最近使用情況來排序記錄ProcessRecord;</processrecord>
- 其中第一個元素代表的便是最近最少使用的進(jìn)程;
- updateLruProcessLocked()更新進(jìn)程隊列位置;
- mRemovedProcesses:數(shù)據(jù)類型為ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">,記錄所有需要強制移除的進(jìn)程;</processrecord>
- mProcessesToGc:數(shù)據(jù)類型為ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">,記錄系統(tǒng)進(jìn)入idle狀態(tài)需執(zhí)行g(shù)c操作的進(jìn)程;</processrecord>
- mPendingPssProcesses:數(shù)據(jù)類型為ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">,記錄將要收集內(nèi)存使用數(shù)據(jù)PSS的進(jìn)程;</processrecord>
- mProcessesOnHold:數(shù)據(jù)類型為ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">,記錄剛開機(jī)過程,系統(tǒng)還沒與偶準(zhǔn)備就緒的情況下, 所有需要啟動的進(jìn)程都放入到該隊列;</processrecord>
- mPersistentStartingProcesses:數(shù)據(jù)類型ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">,正在啟動的persistent進(jìn)程;</processrecord>
- mHomeProcess: 記錄包含home Activity所在的進(jìn)程;
- mPreviousProcess:記錄用戶上一次剛訪問的進(jìn)程;其中mPreviousProcessVisibleTime記錄上一個進(jìn)程的用戶訪問時間;
- mProcessList: 數(shù)據(jù)類型ProcessList,用于進(jìn)程管理,Adj常量定義位于該文件;
其中最為常見的是mProcessNames,mPidsSelfLocked,mLruProcesses這3個對象;
2.3 進(jìn)程與組件的關(guān)聯(lián)
系統(tǒng)AMS這邊是由ProcessRecord對象記錄進(jìn)程,進(jìn)程自身比較重要成員變量如下:
- processName:記錄進(jìn)程名,默認(rèn)情況下進(jìn)程名和該進(jìn)程運行的第一個apk的包名是相同的,當(dāng)然也可以自定義進(jìn)程名;
- pid: 記錄進(jìn)程pid,該值在由進(jìn)程創(chuàng)建時內(nèi)核所分配的。
- thread:執(zhí)行完attachApplicationLocked()方法,會把客戶端進(jìn)程ApplicationThread的binder服務(wù)的代理端傳遞到 AMS,并保持到ProcessRecord的成員變量thread;
- ProcessRecord.makeActive,賦值;
- ProcessRecord.makeInactive,清空;
- info:記錄運行在該進(jìn)程的第一個應(yīng)用;
- pkgList: 記錄運行在該進(jìn)程中所有的包名,比如通過addPackage()添加;
- pkgDeps:記錄該進(jìn)程所依賴的包名,比如通過addPackageDependency()添加;
- lastActivityTime:每次updateLruProcessLocked()過程會更新該值;
- killedByAm:當(dāng)值為true,意味著該進(jìn)程是被AMS所殺,而非由于內(nèi)存低而被LMK所殺;
- killed:當(dāng)值為true,意味著該進(jìn)程被殺,不論是AMS還是其他方式;
- waitingToKill:比如cleanUpRemovedTaskLocked()過程會賦值為”remove task”,當(dāng)該進(jìn)程處于后臺且
任一組件都運行在某個進(jìn)程,再來說說ProcessRecord對象中與組件的關(guān)聯(lián)關(guān)系:
| 成員變量 | 說明 | 對應(yīng)組件 |
|---|---|---|
| activities | 記錄進(jìn)程的ActivityRecord列表 | Activity |
| services | 記錄進(jìn)程的ActivityRecord列表 | Service |
| executingServices | 記錄進(jìn)程的正在執(zhí)行的ActivityRecord列表 | Service |
| connections | 記錄該進(jìn)程bind的ConnectionRecord集合 | Service |
| receivers | 動態(tài)注冊的廣播接收者ReceiverList集合 | Broadcast |
| curReceiver | 當(dāng)前正在處理的一個廣播BroadcastRecord | Broadcast |
| pubProviders | 該進(jìn)程發(fā)布的ContentProviderRecord的map表 | ContentProvider |
| conProviders | 該進(jìn)程所請求的ContentProviderConnection列表 | ContentProvider |
說明:
- connections:舉例來說,進(jìn)程A調(diào)用bindService()方法去bind遠(yuǎn)程進(jìn)程B的Service。 此時會在進(jìn)程A的ProcessRecord.connections添加一個ConnectionRecord.
- pubProviders: 該進(jìn)程所有對外發(fā)布的ContentProvider信息,這是是以ArrayMap形式保存,即 以provider的name為key,以ContentProviderRecord為value的鍵值對結(jié)構(gòu)體。
- conProviders: 當(dāng)進(jìn)程A調(diào)用query()的過程,會執(zhí)行g(shù)etContentProvider()方法去向進(jìn)程B請求 provider的代理。此時會在進(jìn)程A的ProcessRecord.conProviders添加一個ContentProviderConnection。
三. AMS的組件管理
組件啟動,先填充完進(jìn)程信息,接下來還需要完善組件本身的信息,各個組件在system_server的核心信息記錄如下:
- Service的信息記錄在ActiveServices和AMS
- Broadcast信息記錄在BroadcastQueue和AMS
- Activity信息記錄在ActivityStack,ActivityStackSupervisor,以及AMS;
- Provider信息記錄在ProviderMap和AMS;
可見,AMS是整個四大組件最為核心的對象,所有組件都或多或少依賴該對象的數(shù)據(jù)結(jié)構(gòu)信息。 關(guān)系圖如下:點擊查看大圖
[圖片上傳中...(image-5a3c91-1513257973227-1)]
3.1 Activity
AMS對象
public final class ActivityManagerService extends ...{
//當(dāng)前聚焦的Activity
ActivityRecord mFocusedActivity = null;
//用于管理各個Activity棧
final ActivityStackSupervisor mStackSupervisor;
}
ASS對象
public final class ActivityStackSupervisor implements DisplayListener {
//桌面app所在棧
ActivityStack mHomeStack;
//當(dāng)前可以接受Input事件,或許啟動下一個Activity的棧
ActivityStack mFocusedStack;
//當(dāng)該值等于mFocusedStack,代表當(dāng)前棧頂?shù)腁ctivity已進(jìn)入resumed狀態(tài);
//當(dāng)該值等于上一個舊棧時,代表正處理activity切換狀態(tài);
private ActivityStack mLastFocusedStack;
//在完成相應(yīng)目標(biāo)前,等待新的Activity成為可見的Activity列表
final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
//等待找到下一個可見Activity的等待列表
final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>();
//等待找到下一個已啟動Activity的等待列表
final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>();
//等待上一個activity安置完成,則即將進(jìn)入被stopped的Activity列表
final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
//等待上一個activity安置完成,則即將進(jìn)入被finished的Activity列表
final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
//即將進(jìn)入sleep狀態(tài)的進(jìn)程所對應(yīng)的Activity列表
final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
}
AS對象
final class ActivityStack{
//記錄該棧中所有的task
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
//按LRU方式排序的Activity列表,隊尾成員是最新活動的Activity
final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
//正在執(zhí)行pausing過程的Activity
ActivityRecord mPausingActivity = null;
//已處于paused狀態(tài)的Activity
ActivityRecord mLastPausedActivity = null;
//已處于Resumed狀態(tài)的Activity
ActivityRecord mResumedActivity = null;
}
3.2 Service
[-> ActiveServices.java]
public final class ActiveServices {
//記錄不同User下所有的Service信息
final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();
//bind service的連接信息,以IServiceConnection的Bp端作為Keys
final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections = new ArrayMap<>();
//已請求啟動但尚未啟動的Service列表
final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>();
//crash后需要計劃重啟的Service列表
final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<>();
//正在執(zhí)行destroyed的service列表
final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<>();
}
3.3 Broadcast
[-> ActivityManagerService.java]
public final class ActivityManagerService extends ...{
//前臺廣播隊列
BroadcastQueue mFgBroadcastQueue;
//后臺廣播隊列
BroadcastQueue mBgBroadcastQueue;
//廣播隊列數(shù)組,也就是前臺和后臺廣播隊列
final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
//粘性廣播,[userId,action,ArrayList<Intent>]
final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts;
//動態(tài)注冊的廣播接收者,其中key為客戶端InnerReceiver的Bp端,value為ReceiverList
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
//從廣播intent到已注冊接收者的解析器
final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver;
}
[-> BroadcastQueue.java]
public final class BroadcastQueue{
//并行廣播列表
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
//串行廣播列表
final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>();
//即將要處理的串行廣播,等待目標(biāo)進(jìn)程創(chuàng)建完成。每個廣播隊列只有一個,其他必須等待該廣播完成。
BroadcastRecord mPendingBroadcast = null;
}
3.4 Provider
[-> ActivityManagerService.java]
public final class ActivityManagerService extends ...{
//記錄系統(tǒng)所有的provider信息
final ProviderMap mProviderMap;
//記錄有client正在等待的provider列表,當(dāng)provider發(fā)布完成則從該隊列移除
final ArrayList<ContentProviderRecord> mLaunchingProviders;
}
[-> ProviderMap.java]
public final class ProviderMap {
//以provider名字(auth)為key的方式所記錄的provider信息
private final HashMap<String, ContentProviderRecord> mSingletonByName;
//以provider組件名(ComponentName)為key的方式所記錄的provider信息
private final HashMap<ComponentName, ContentProviderRecord> mSingletonByClass;
//記錄不同UserId下的,以auth為key的方式所記錄的provider信息
private final SparseArray<HashMap<String, ContentProviderRecord>> mProvidersByNamePerUser;
//記錄不同UserId下的,以ComponentName為key的方式所記錄的provider信息
private final SparseArray<HashMap<ComponentName, ContentProviderRecord>> mProvidersByClassPerUser;
}
同一個provider組件名,可能對應(yīng)多個provider名。
四. App端的組件信息
關(guān)系圖如下:點擊查看大圖
[圖片上傳中...(image-6b8d58-1513257973227-0)]
App端的組件信息,都保存在ActivityThread和LoadedApk這兩個對象,主要保存信息:
- ActivityThread:記錄provider, activity, service在客戶端的相關(guān)信息;
- LoadedApk: 記錄動態(tài)注冊的廣播接收器,以及bind方式啟動service在客戶端的相關(guān)信息;