startActivity流程(上)

介紹

這篇文章是講,從手機桌面(Launcher)點擊一個未啓動app的圖標到這個app啓動完成的流程(冷啓動)。android

整體流程

startActivity流程
Launcher、AMS、Zygote、app都處於不一樣的進程,他們之間須要跨進程才能通訊。
數據庫

用戶點擊Launcher的app圖標後,Launcher通知AMS,若是目標app未啓動(冷啓動),AMS會經過Socket來通知Zygote去建立進程,Zygote就fork出咱們要啓動的app進程。
緊接着app要打開HomeActivity,須要與AMS交互
windows

  1. app -> AMS : 由於AMS啓動時,就註冊到ServiceManager了,因此app調用getService就能從ServiceManager獲取到AMS的代理類IActivityManager(客戶端)。app從而經過IActivityManager調用AMS(服務端)的方法。
  2. AMS -> app : AMS準備一個IBinder,叫IApplicationThread(服務端)。當app進程啓動完成後,會調用IApplicationThread的attachApplication方法,把app的代理類ApplicationThread(客戶端)做爲參數傳給AMS。AMS能夠調用ApplicationThread的方法從而控制app。

IApplicationThread的實現類是ActivityThread的內部類ApplicationThread數據結構

看完流程圖,咱們再來看時序圖
在這裏插入圖片描述
圖中的4就是attachApplication的過程,把app的代理類ApplicationThread交給AMS。
圖中的5就是AMS作完一些處理後,經過app的代理類ApplicationThread來啓動app的HomeActivity。


app

涉及的數據結構

在看源碼以前,須要先了解幾個重要的數據結構異步

ProcessRecord(進程)

第一類數據:描述身份的數據ide

  • ApplicationInfo info:AndroidManifest.xml中定義的Application信息
  • boolean isolated:是否是isolated進程
  • int uid:進程uid
  • int userId:這個是android作的多用戶系統id,就像windows能夠登陸不少用戶同樣,android也但願能夠實現相似的多用戶
  • String processName:進程名字,默認狀況下是包名
  • UidRecord uidRecord:記錄已經使用的uid
  • IApplicationThread thread:這個很重要,它是ApplicationThread的客戶端,AMS就是經過這個對象給apk進程發送異步消息的(管理四大組件的消息),因此只有這個對象不爲空的狀況下,才表明apk進程可使用了
  • int pid:進程的pid
  • String procStatFile:proc目錄下每個進程都有一個以pid命名的目錄文件,這個目錄下記載着進程的詳細信息,這個目錄及目錄下的文件是內核建立的, proc是內核文件系統,proc就是process的縮寫,涉及的目的就是導出進程內核信息
  • int[] gids:gid組
  • CompatibilityInfo compat : 兼容性信息
  • String requiredAbi : abi信息
  • String instructionSet : 指令集信息

第二類數據:描述進程中組件的數據ui

  • pkgList:進程中運行的包
  • ArraySet pkgDeps:進程運行依賴的包
  • ArrayList activities:進程啓動的全部的activity組件記錄表
  • ArraySet services:進程啓動的全部的service組件記錄表
  • ArraySet executingServices:正在運行(executing)是怎麼定義的?首先須要明確的是系統是怎麼控制組件的?發送消息給apk進程,apk進程處理消息,上報消息完成,這被定義爲一個完整的執行過程,所以正在執行(executing)被定義爲發送消息到上報完成這段時間
  • ArraySet connections:綁定service的客戶端記錄表
  • ArraySet receivers:廣播接收器的記錄表
  • ContentProviderRecord pubProviders:pub是publish(發佈)的意思,ContentProvider須要安裝而後把本身發佈到系統(AMS)中後,才能使用,安裝指的是apk進程加載ContentProvider子類、初始化建立數據庫等過程,發佈是將ContentProvider的binder客戶端註冊到AMS中
  • ArrayList conProviders:使用ContentProvider的客戶端記錄表
  • BroadcastRecord curReceiver:當前進程正在執行的廣播 在本節中以上組件信息只是作一個簡單的描述,之後單獨分析組件管理的時候在詳細介紹

此外還有描述進程狀態的數據、和pss相關的數據、和時間相關的數據、crash和anr相關的數據、和instrumentation相關的數據、電源信息和調試信息等,spa

ActivityRecord

Activity在AMS內部是以ActivityRecord的形式存在的,Activity和ActivityRecord是一一對應的。線程

  • ProcessRecord app:跑在哪一個進程
  • TaskRecord task :跑在哪一個task
  • ActivityInfo info :Activity信息
  • int mActivityType:Activity類型
  • ActivityState state:Activity狀態
  • ApplicationInfo appInfo :跑在哪一個app
  • ComponentName realActivity :組件名
  • String packageName :包名
  • String processName :進程名
  • int launchMode:啓動模式
  • int userId :該Activity運行在哪一個用戶id

mActivityType

  • APPLICATION_ACTIVITY_TYPE:普通應用類型
  • HOME_ACTIVITY_TYPE:桌面類型
  • RECENTS_ACTIVITY_TYPE:最近任務類型

ActivityState

  • INITIALIZING
  • RESUMED:已恢復
  • PAUSING
  • PAUSED:已暫停
  • STOPPING
  • STOPPED:已中止
  • FINISHING
  • DESTROYING
  • DESTROYED:已銷燬

ActivityRecord是在ActivityStarter的startActivity方法裏建立的

TaskRecord

任務棧TaskRecord,內部維護一個 ArrayList 用來保存ActivityRecord。

  • ActivityStack stack:當前所屬的stack
  • ArrayList mActivities:當前task的全部Activity列表
  • int taskId
  • String affinity:是指root activity的affinity,即該Task中第一個Activity
  • int mCallingUid
  • String mCallingPackage:調用者的包名

TaskRecord是在ActivityStarter的setTaskFromReuseOrCreateNewTask裏建立的。

ActivityStack

ActivityStack,內部維護了一個 ArrayList ,用來管理TaskRecord。
手機有三個虛擬按鍵,按最右邊的正方形按鍵,會顯示最近任務,這個最近任務就是一個ActivityStack,桌面應用也是一個ActivityStack。

ArrayList mTaskHistory //保存全部的Task列表
ArrayList mStacks; //全部stack列表
final int mStackId;
int mDisplayId;
ActivityRecord mPausingActivity //正在pause
ActivityRecord mLastPausedActivity
ActivityRecord mResumedActivity //已經resumed
ActivityRecord mLastStartedActivity
全部前臺stack的mResumedActivity的state == RESUMED, 則表示allResumedActivitiesComplete, 此時mLastFocusedStack = mFocusedStack;







ActivityStackSupervisor

ActivityStackSupervisor,顧名思義,就是用來管理ActivityStack的

  • ActivityStack mHomeStack:桌面的stack
  • ActivityStack mFocusedStack:當前聚焦stack
  • ActivityStack mLastFocusedStack:正在切換
  • SparseArray mActivityDisplays:displayId爲key
  • SparseArray mActivityContainers: mStackId爲key
  • home的棧ID等於0,即HOME_STACK_ID = 0;

ActivityStackSupervisor內部有兩個不一樣的ActivityStack對象:mHomeStack、mFocusedStack,用來管理不一樣的任務。
ActivityStackSupervisor內部包含了建立ActivityStack對象的方法。

AMS初始化時會建立一個ActivityStackSupervisor對象

在這裏插入圖片描述

詳細的流程

在這裏插入圖片描述

  • Instrumentation:管理Activity的生命週期以及啓動
  • ActivityManagerProxy:AMS的代理對象
  • ApplicationThreadProxy:啓動APP的代理對象
  • ApplicationThread是一個Binder服務,不是主線程

第9步是經過Handler來跨線程通訊,從子線程ApplicationThread走到主線程ActivityThread。

相關文章
相關標籤/搜索