Android系統中用於描述進程的數據結構是ProcessRecord對象,AMS便是管理進程的核心模塊。四大組件 (Activity,Service, BroadcastReceiver, ContentProvider)定義在AndroidManifest.xml文件, 每一項都可以用屬性android:process指定所運行的進程。同一個app可以運行在通過一個進程,也可以運行在多個進程, 甚至多個app可以共享同一個進程。
以一幅圖來展示AMS管理進程的相關成員變量以及ProcessRecord對象:
進程與AMS的關聯
這里只介紹AMS的進程相關的成員變量:
- mProcessNames:數據類型為ProcessMap,以進程名和userId為key來記錄ProcessRecord;
- 添加進程,addProcessNameLocked()
- 刪除進程,removeProcessNameLocked()
- mPidsSelfLocked: 數據類型為SparseArray,以進程pid為key來記錄ProcessRecord;
- startProcessLocked(),移除已存在進程,增加新創建進程pid信息;
- removeProcessLocked,processStartTimedOutLocked,cleanUpApplicationRecordLocked移除進程;
- mLruProcesses:數據類型為ArrayList,以進程最近使用情況來排序記錄ProcessRecord;
- 其中第一個元素代表的便是最近最少使用的進程;
- updateLruProcessLocked()更新進程隊列位置;
- mRemovedProcesses:數據類型為ArrayList,記錄所有需要強制移除的進程;
- mProcessesToGc:數據類型為ArrayList,記錄系統進入idle狀態需執行gc操作的進程;
- mPendingPssProcesses:數據類型為ArrayList,記錄將要收集內存使用數據PSS的進程;
- mProcessesOnHold:數據類型為ArrayList,記錄剛開機過程,系統還沒與偶准備就緒的情況下, 所有需要啟動的進程都放入到該隊列;
- mPersistentStartingProcesses:數據類型ArrayList,正在啟動的persistent進程;
- mHomeProcess: 記錄包含home Activity所在的進程;
- mPreviousProcess:記錄用戶上一次剛訪問的進程;其中mPreviousProcessVisibleTime記錄上一個進程的用戶訪問時間;
- mProcessList: 數據類型ProcessList,用於進程管理,Adj常量定義位於該文件;
其中最為常見的是mProcessNames,mPidsSelfLocked,mLruProcesses這3個對象;
進程與組件的關聯
系統AMS這邊是由ProcessRecord對象記錄進程,進程自身比較重要成員變量如下:
- processName:記錄進程名,默認情況下進程名和該進程運行的第一個apk的包名是相同的,當然也可以自定義進程名;
- pid: 記錄進程pid,該值在由進程創建時內核所分配的。
- thread:執行完attachApplicationLocked()方法,會把客戶端進程ApplicationThread的binder服務的代理端傳遞到 AMS,並保持到ProcessRecord的成員變量thread;
- ProcessRecord.makeActive,賦值;
- ProcessRecord.makeInactive,清空;
- info:記錄運行在該進程的第一個應用;
- pkgList: 記錄運行在該進程中所有的包名,比如通過addPackage()添加;
- pkgDeps:記錄該進程所依賴的包名,比如通過addPackageDependency()添加;
- lastActivityTime:每次updateLruProcessLocked()過程會更新該值;
- killedByAm:當值為true,意味着該進程是被AMS所殺,而非由於內存低而被LMK所殺;
- killed:當值為true,意味着該進程被殺,不論是AMS還是其他方式;
- waitingToKill:比如cleanUpRemovedTaskLocked()過程會賦值為”remove task”,當該進程處於后台且
任一組件都運行在某個進程,再來說說ProcessRecord對象中與組件的關聯關系:
成員變量 | 說明 | 對應組件 |
---|---|---|
activities | 記錄進程的ActivityRecord列表 | Activity |
services | 記錄進程的ActivityRecord列表 | Service |
executingServices | 記錄進程的正在執行的ActivityRecord列表 | Service |
connections | 記錄該進程bind的ConnectionRecord集合 | Service |
receivers | 動態注冊的廣播接收者ReceiverList集合 | Broadcast |
curReceiver | 當前正在處理的一個廣播BroadcastRecord | Broadcast |
pubProviders | 該進程發布的ContentProviderRecord的map表 | ContentProvider |
conProviders | 該進程所請求的ContentProviderConnection列表 | ContentProvider |
說明:
- connections:舉例來說,進程A調用bindService()方法去bind遠程進程B的Service。 此時會在進程A的ProcessRecord.connections添加一個ConnectionRecord.
- pubProviders: 該進程所有對外發布的ContentProvider信息,這是是以ArrayMap形式保存,即 以provider的name為key,以ContentProviderRecord為value的鍵值對結構體。
- conProviders: 當進程A調用query()的過程,會執行getContentProvider()方法去向進程B請求 provider的代理。此時會在進程A的ProcessRecord.conProviders添加一個ContentProviderConnection。
AMS的組件管理
組件啟動,先填充完進程信息,接下來還需要完善組件本身的信息,各個組件在system_server的核心信息記錄如下:
- Service的信息記錄在ActiveServices和AMS
- Broadcast信息記錄在BroadcastQueue和AMS
- Activity信息記錄在ActivityStack,ActivityStackSupervisor,以及AMS;
- Provider信息記錄在ProviderMap和AMS;
可見,AMS是整個四大組件最為核心的對象,所有組件都或多或少依賴該對象的數據結構信息。 關系圖如下:
Activity
AMS對象
public final class ActivityManagerService extends ...{ //當前聚焦的Activity ActivityRecord mFocusedActivity = null; //用於管理各個Activity棧 final ActivityStackSupervisor mStackSupervisor; }
ASS對象
public final class ActivityStackSupervisor implements DisplayListener { //桌面app所在棧 ActivityStack mHomeStack; //當前可以接受Input事件,或許啟動下一個Activity的棧 ActivityStack mFocusedStack; //當該值等於mFocusedStack,代表當前棧頂的Activity已進入resumed狀態; //當該值等於上一個舊棧時,代表正處理activity切換狀態; private ActivityStack mLastFocusedStack; //在完成相應目標前,等待新的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安置完成,則即將進入被stopped的Activity列表 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>(); //等待上一個activity安置完成,則即將進入被finished的Activity列表 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>(); //即將進入sleep狀態的進程所對應的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<>(); //正在執行pausing過程的Activity ActivityRecord mPausingActivity = null; //已處於paused狀態的Activity ActivityRecord mLastPausedActivity = null; //已處於Resumed狀態的Activity ActivityRecord mResumedActivity = null; }
Service
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<>(); //正在執行destroyed的service列表 final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<>(); }
Broadcast
public final class ActivityManagerService extends ...{ //前台廣播隊列 BroadcastQueue mFgBroadcastQueue; //后台廣播隊列 BroadcastQueue mBgBroadcastQueue; //廣播隊列數組,也就是前台和后台廣播隊列 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; //粘性廣播,[userId,action,ArrayList<Intent>] final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts; //動態注冊的廣播接收者,其中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<>(); //即將要處理的串行廣播,等待目標進程創建完成。每個廣播隊列只有一個,其他必須等待該廣播完成。 BroadcastRecord mPendingBroadcast = null; }
Provider
public final class ActivityManagerService extends ...{ //記錄系統所有的provider信息 final ProviderMap mProviderMap; //記錄有client正在等待的provider列表,當provider發布完成則從該隊列移除 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組件名,可能對應多個provider名。
App端的組件信息
App端的組件信息,都保存在ActivityThread和LoadedApk這兩個對象,主要保存信息:
- ActivityThread:記錄provider, activity, service在客戶端的相關信息;
- LoadedApk: 記錄動態注冊的廣播接收器,以及bind方式啟動service在客戶端的相關信息