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ǎn)單的幾行代碼便可完成任一組件的啟動(dòng)/結(jié)束、 生命周期的操作面殖。然而每一次看似簡(jiǎn)單的操作,背后所有的復(fù)雜工作都是交由系統(tǒng)來完成哭廉。
組件啟動(dòng)后脊僚,首先需要依賴進(jìn)程,那么就需要先創(chuàng)建進(jìn)程遵绰,系統(tǒng)需要記錄每個(gè)進(jìn)程辽幌,這便產(chǎn)生了ProcessRecord。 Android中椿访,對(duì)于進(jìn)程的概念被弱化乌企,通過抽象后的四大組件。讓開發(fā)者幾乎感受不到進(jìn)程的存在成玫。 當(dāng)應(yīng)用退出時(shí)加酵,進(jìn)程也并非馬上退出,而是成為cache/empty進(jìn)程哭当,下次該應(yīng)用再啟動(dòng)的時(shí)候虽画,可以不用 再創(chuàng)建進(jìn)程直接初始化組件即可,提高啟動(dòng)速度荣病。先來說一說進(jìn)程码撰。
二. 進(jìn)程管理
Android系統(tǒng)中用于描述進(jìn)程的數(shù)據(jù)結(jié)構(gòu)是ProcessRecord對(duì)象,AMS便是管理進(jìn)程的核心模塊个盆。四大組件 (Activity,Service, BroadcastReceiver, ContentProvider)定義在AndroidManifest.xml文件脖岛, 每一項(xiàng)都可以用屬性android:process指定所運(yùn)行的進(jìn)程。同一個(gè)app可以運(yùn)行在通過一個(gè)進(jìn)程颊亮,也可以運(yùn)行在多個(gè)進(jìn)程柴梆, 甚至多個(gè)app可以共享同一個(gè)進(jìn)程。例如:AndroidManifest.xml中定義Service:
<service android:name =".GityuanService" android:process =":remote" >
<intent-filter>
<action android:name ="com.action.gityuan" />
</intent-filter>
</service>
GityuanService這個(gè)服務(wù)運(yùn)行在remote進(jìn)程终惑。
2.1 進(jìn)程關(guān)系圖
以一幅圖來展示AMS管理進(jìn)程的相關(guān)成員變量以及ProcessRecord對(duì)象:
[圖片上傳中...(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>
- 其中第一個(gè)元素代表的便是最近最少使用的進(jìn)程;
- updateLruProcessLocked()更新進(jìn)程隊(duì)列位置嫉嘀;
- mRemovedProcesses:數(shù)據(jù)類型為ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">炼邀,記錄所有需要強(qiáng)制移除的進(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)備就緒的情況下降铸, 所有需要啟動(dòng)的進(jìn)程都放入到該隊(duì)列;</processrecord>
- mPersistentStartingProcesses:數(shù)據(jù)類型ArrayList<processrecord style="box-sizing: border-box; user-select: text !important;">摇零,正在啟動(dòng)的persistent進(jìn)程推掸;</processrecord>
- mHomeProcess: 記錄包含home Activity所在的進(jìn)程;
- mPreviousProcess:記錄用戶上一次剛訪問的進(jìn)程驻仅;其中mPreviousProcessVisibleTime記錄上一個(gè)進(jìn)程的用戶訪問時(shí)間谅畅;
- mProcessList: 數(shù)據(jù)類型ProcessList,用于進(jìn)程管理噪服,Adj常量定義位于該文件毡泻;
其中最為常見的是mProcessNames,mPidsSelfLocked粘优,mLruProcesses這3個(gè)對(duì)象仇味;
2.3 進(jìn)程與組件的關(guān)聯(lián)
系統(tǒng)AMS這邊是由ProcessRecord對(duì)象記錄進(jìn)程,進(jìn)程自身比較重要成員變量如下:
- processName:記錄進(jìn)程名雹顺,默認(rèn)情況下進(jìn)程名和該進(jìn)程運(yùn)行的第一個(gè)apk的包名是相同的丹墨,當(dāng)然也可以自定義進(jìn)程名;
- pid: 記錄進(jìn)程pid嬉愧,該值在由進(jìn)程創(chuàng)建時(shí)內(nèi)核所分配的贩挣。
- thread:執(zhí)行完attachApplicationLocked()方法,會(huì)把客戶端進(jìn)程ApplicationThread的binder服務(wù)的代理端傳遞到 AMS,并保持到ProcessRecord的成員變量thread王财;
- ProcessRecord.makeActive卵迂,賦值;
- ProcessRecord.makeInactive搪搏,清空狭握;
- info:記錄運(yùn)行在該進(jìn)程的第一個(gè)應(yīng)用;
- pkgList: 記錄運(yùn)行在該進(jìn)程中所有的包名疯溺,比如通過addPackage()添加论颅;
- pkgDeps:記錄該進(jìn)程所依賴的包名,比如通過addPackageDependency()添加囱嫩;
- lastActivityTime:每次updateLruProcessLocked()過程會(huì)更新該值恃疯;
- killedByAm:當(dāng)值為true,意味著該進(jìn)程是被AMS所殺墨闲,而非由于內(nèi)存低而被LMK所殺今妄;
- killed:當(dāng)值為true,意味著該進(jìn)程被殺鸳碧,不論是AMS還是其他方式盾鳞;
- waitingToKill:比如cleanUpRemovedTaskLocked()過程會(huì)賦值為”remove task”,當(dāng)該進(jìn)程處于后臺(tái)且
任一組件都運(yùn)行在某個(gè)進(jìn)程瞻离,再來說說ProcessRecord對(duì)象中與組件的關(guān)聯(lián)關(guān)系:
成員變量 | 說明 | 對(duì)應(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 | 動(dòng)態(tài)注冊(cè)的廣播接收者ReceiverList集合 | Broadcast |
curReceiver | 當(dāng)前正在處理的一個(gè)廣播BroadcastRecord | Broadcast |
pubProviders | 該進(jìn)程發(fā)布的ContentProviderRecord的map表 | ContentProvider |
conProviders | 該進(jìn)程所請(qǐng)求的ContentProviderConnection列表 | ContentProvider |
說明:
- connections:舉例來說腾仅,進(jìn)程A調(diào)用bindService()方法去bind遠(yuǎn)程進(jìn)程B的Service。 此時(shí)會(huì)在進(jìn)程A的ProcessRecord.connections添加一個(gè)ConnectionRecord.
- pubProviders: 該進(jìn)程所有對(duì)外發(fā)布的ContentProvider信息套利,這是是以ArrayMap形式保存推励,即 以provider的name為key,以ContentProviderRecord為value的鍵值對(duì)結(jié)構(gòu)體。
- conProviders: 當(dāng)進(jìn)程A調(diào)用query()的過程肉迫,會(huì)執(zhí)行g(shù)etContentProvider()方法去向進(jìn)程B請(qǐng)求 provider的代理验辞。此時(shí)會(huì)在進(jìn)程A的ProcessRecord.conProviders添加一個(gè)ContentProviderConnection。
三. AMS的組件管理
組件啟動(dòng)喊衫,先填充完進(jìn)程信息跌造,接下來還需要完善組件本身的信息,各個(gè)組件在system_server的核心信息記錄如下:
- Service的信息記錄在ActiveServices和AMS
- Broadcast信息記錄在BroadcastQueue和AMS
- Activity信息記錄在ActivityStack族购,ActivityStackSupervisor鼻听,以及AMS;
- Provider信息記錄在ProviderMap和AMS;
可見,AMS是整個(gè)四大組件最為核心的對(duì)象联四,所有組件都或多或少依賴該對(duì)象的數(shù)據(jù)結(jié)構(gòu)信息撑碴。 關(guān)系圖如下:點(diǎn)擊查看大圖
[圖片上傳中...(image-5a3c91-1513257973227-1)]
3.1 Activity
AMS對(duì)象
public final class ActivityManagerService extends ...{
//當(dāng)前聚焦的Activity
ActivityRecord mFocusedActivity = null;
//用于管理各個(gè)Activity棧
final ActivityStackSupervisor mStackSupervisor;
}
ASS對(duì)象
public final class ActivityStackSupervisor implements DisplayListener {
//桌面app所在棧
ActivityStack mHomeStack;
//當(dāng)前可以接受Input事件,或許啟動(dòng)下一個(gè)Activity的棧
ActivityStack mFocusedStack;
//當(dāng)該值等于mFocusedStack朝墩,代表當(dāng)前棧頂?shù)腁ctivity已進(jìn)入resumed狀態(tài)醉拓;
//當(dāng)該值等于上一個(gè)舊棧時(shí)伟姐,代表正處理activity切換狀態(tài);
private ActivityStack mLastFocusedStack;
//在完成相應(yīng)目標(biāo)前亿卤,等待新的Activity成為可見的Activity列表
final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
//等待找到下一個(gè)可見Activity的等待列表
final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>();
//等待找到下一個(gè)已啟動(dòng)Activity的等待列表
final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>();
//等待上一個(gè)activity安置完成愤兵,則即將進(jìn)入被stopped的Activity列表
final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
//等待上一個(gè)activity安置完成,則即將進(jìn)入被finished的Activity列表
final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
//即將進(jìn)入sleep狀態(tài)的進(jìn)程所對(duì)應(yīng)的Activity列表
final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>();
}
AS對(duì)象
final class ActivityStack{
//記錄該棧中所有的task
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
//按LRU方式排序的Activity列表排吴,隊(duì)尾成員是最新活動(dòng)的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<>();
//已請(qǐng)求啟動(dòng)但尚未啟動(dòng)的Service列表
final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>();
//crash后需要計(jì)劃重啟的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 ...{
//前臺(tái)廣播隊(duì)列
BroadcastQueue mFgBroadcastQueue;
//后臺(tái)廣播隊(duì)列
BroadcastQueue mBgBroadcastQueue;
//廣播隊(duì)列數(shù)組,也就是前臺(tái)和后臺(tái)廣播隊(duì)列
final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
//粘性廣播钻哩,[userId屹堰,action,ArrayList<Intent>]
final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts;
//動(dòng)態(tài)注冊(cè)的廣播接收者街氢,其中key為客戶端InnerReceiver的Bp端扯键,value為ReceiverList
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
//從廣播intent到已注冊(cè)接收者的解析器
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)建完成荣刑。每個(gè)廣播隊(duì)列只有一個(gè),其他必須等待該廣播完成伦乔。
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ā)布完成則從該隊(duì)列移除
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;
}
同一個(gè)provider組件名爱只,可能對(duì)應(yīng)多個(gè)provider名。
四. App端的組件信息
關(guān)系圖如下:點(diǎn)擊查看大圖
[圖片上傳中...(image-6b8d58-1513257973227-0)]
App端的組件信息斥杜,都保存在ActivityThread和LoadedApk這兩個(gè)對(duì)象虱颗,主要保存信息:
- ActivityThread:記錄provider, activity, service在客戶端的相關(guān)信息沥匈;
- LoadedApk: 記錄動(dòng)態(tài)注冊(cè)的廣播接收器蔗喂,以及bind方式啟動(dòng)service在客戶端的相關(guān)信息;