ActivityManagerService數據結構ProcessRecord(一)


Android系統中用於描述進程的數據結構是ProcessRecord對象,AMS便是管理進程的核心模塊。四大組件 (Activity,Service, BroadcastReceiver, ContentProvider)定義在AndroidManifest.xml文件, 每一項都可以用屬性android:process指定所運行的進程。同一個app可以運行在通過一個進程,也可以運行在多個進程, 甚至多個app可以共享同一個進程。

以一幅圖來展示AMS管理進程的相關成員變量以及ProcessRecord對象:

進程與AMS的關聯

這里只介紹AMS的進程相關的成員變量:

  1. mProcessNames:數據類型為ProcessMap,以進程名和userId為key來記錄ProcessRecord;
    • 添加進程,addProcessNameLocked()
    • 刪除進程,removeProcessNameLocked()
  2. mPidsSelfLocked: 數據類型為SparseArray,以進程pid為key來記錄ProcessRecord;
    • startProcessLocked(),移除已存在進程,增加新創建進程pid信息;
    • removeProcessLocked,processStartTimedOutLocked,cleanUpApplicationRecordLocked移除進程;
  3. mLruProcesses:數據類型為ArrayList,以進程最近使用情況來排序記錄ProcessRecord;
    • 其中第一個元素代表的便是最近最少使用的進程;
    • updateLruProcessLocked()更新進程隊列位置;
  4. mRemovedProcesses:數據類型為ArrayList,記錄所有需要強制移除的進程;
  5. mProcessesToGc:數據類型為ArrayList,記錄系統進入idle狀態需執行gc操作的進程;
  6. mPendingPssProcesses:數據類型為ArrayList,記錄將要收集內存使用數據PSS的進程;
  7. mProcessesOnHold:數據類型為ArrayList,記錄剛開機過程,系統還沒與偶准備就緒的情況下, 所有需要啟動的進程都放入到該隊列;
  8. mPersistentStartingProcesses:數據類型ArrayList,正在啟動的persistent進程;
  9. mHomeProcess: 記錄包含home Activity所在的進程;
  10. mPreviousProcess:記錄用戶上一次剛訪問的進程;其中mPreviousProcessVisibleTime記錄上一個進程的用戶訪問時間;
  11. mProcessList: 數據類型ProcessList,用於進程管理,Adj常量定義位於該文件;

其中最為常見的是mProcessNames,mPidsSelfLocked,mLruProcesses這3個對象;

進程與組件的關聯

系統AMS這邊是由ProcessRecord對象記錄進程,進程自身比較重要成員變量如下:

  1. processName:記錄進程名,默認情況下進程名和該進程運行的第一個apk的包名是相同的,當然也可以自定義進程名;
  2. pid: 記錄進程pid,該值在由進程創建時內核所分配的。
  3. thread:執行完attachApplicationLocked()方法,會把客戶端進程ApplicationThread的binder服務的代理端傳遞到 AMS,並保持到ProcessRecord的成員變量thread;
    • ProcessRecord.makeActive,賦值;
    • ProcessRecord.makeInactive,清空;
  4. info:記錄運行在該進程的第一個應用;
  5. pkgList: 記錄運行在該進程中所有的包名,比如通過addPackage()添加;
  6. pkgDeps:記錄該進程所依賴的包名,比如通過addPackageDependency()添加;
  7. lastActivityTime:每次updateLruProcessLocked()過程會更新該值;
  8. killedByAm:當值為true,意味着該進程是被AMS所殺,而非由於內存低而被LMK所殺;
  9. killed:當值為true,意味着該進程被殺,不論是AMS還是其他方式;
  10. 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在客戶端的相關信息

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM