Activity
管理
Activity
是最複雜的一個組件,它負責UI
的顯示以及處理各類輸入事件。Activity
提供窗口供應用在其中繪製界面,同時也提供了各類各樣的控件方便開發。Activity 官網傳送門前端
另外,
Android
中並無對外提供啓動進程的接口,只是在啓動Activity
或Service
時,由系統根據須要來啓動進程。java
Activity
的生命週期關於Activity
的生命週期,咱們先看下官方圖示:
android
Activity
的生命週期圖中隱含了Activity
運行時的三種狀態,分別是:瀏覽器
Activity
位於屏幕的最前端,能夠接受用戶輸入的狀態Activity
被一個透明或半透明的Activity
覆蓋,此時Activity
雖然不能接收用戶的輸入,但仍是可見的Activity
徹底被另外一Activity
覆蓋,不能接受用戶輸入也不可見時當一個Activity
對象的狀態發生變化時,會調用上圖中定義的抽象接口來通知應用。相關描述以下:markdown
onCreate()
:當Activity
對象被建立時調用onStart()
:當Activity
在Framework
中的數據結構準備完畢後調用onResume()
:當Activity
來到棧的最前端變成激活態時調用onPause()
:當Activity
從棧的最前端切換到後臺時,進入暫停態,並調用該方法onStop()
:當Activity
已經徹底不可見時調用onDestroy()
:在銷燬Activity
前,系統會先調用該方法上面的知識在初學Android
時咱們就已經知道了,接下來咱們要從AMS
的角度看下這幾個方法是如何調用的,不過在此以前咱們先熟悉下另外的幾個相關知識:Intent
、Task
與LaunchMode
網絡
Intent
、Task
與LaunchMode
Intent
Intent
是所請求執行動做的抽象描述,一般做爲參數來使用,用於完成各個組件之間的消息傳遞。更爲詳細的姿式能夠參考官網描述:官網傳送門數據結構
Intent
類的相關定義以下:app
public class Intent implements Parcelable, Cloneable {
private String mAction;
private Uri mData;
private String mType;
private String mPackage;
private ComponentName mComponent;
private int mFlags;
private ArraySet<String> mCategories;
private Bundle mExtras;
private Rect mSourceBounds;
private Intent mSelector;
private ClipData mClipData;
}
複製代碼
經常使用字段含義以下:ide
mAction
是一個字符串,用來指明要執行的操做是什麼。
Intent
類中定義了大量的Action
,例如ACTION_VIEW
、ACTION_SEND
等。Action
的做用與具體的功能模塊相關,表達要執行的意圖mData
儲存須要傳遞的數據,類型是URI
。
URI
是統一資源標識符(Uniform Resources Identifier
)的簡稱Web
中的各類資源,如HTML文檔、圖片、文件等URL(Uniform Resource Locator)
是URI
的一種mType
是MIME
格式的字符串,表示數據類型。
MIME
是多功能Internet
郵件擴充服務(Multipurpose Internet Mail Extensions
)的縮寫text/plain``application/x-gzip
等Intent
的匹配速度mComponent
用於指定接收Intent
的目標組件的名稱
mComponent
的類型是ComponentName
,它包含兩個字符串:mPackage
和mClass
,前者用於指定包名,後者用於指定類名Intent
中若是定義了mComponent
,該Intent
將直接發送到指定的組件,不會在經過其餘屬性組合查找mFlags
稱爲標誌,在Intent
類中定義了不少flag
的相關常量。主要分爲兩種
FLAG_ACTIVITY_...
開頭的,用來控制Activity
啓動的相關參數,如FLAG_ACTIVITY_NEW_TASK
FLAG_RECEIVER_...
開頭的,用來進行廣播的參數mCategories
一個包含應處理Intent
組件類型的附加信息的字符串。常見的類別有兩種:
CATEGORY_BROWSABLE
:目標Activity
容許自己經過網絡瀏覽器啓動,以顯示連接引用的數據CATEGORY_LAUNCHER
:該Activity
是任務的初始Activity
Intent
中,但大多數Intent
均不須要類別mExtras
表示全部附加信息的集合。
mExtras
數據類型是Bundle
putExtra()
方法添加extra數據
,每種方法均接受兩個參數:key
和value
Task
Task
是Activity
的集合。Android把用戶一次相關操做中使用的Activity
按照前後順序保存在Task
中,這樣當按back鍵
時就能按照相反的順序回退。函數
Task
像一個棧,之後進先出的方式管理着Activity
。系統運行時內存中會存在着多個Task
,當咱們按recent
鍵時,會彈出一個選擇列表,這個列表就是系統中存在的Task
的集合,選擇一個Task
將把它所包含的Activity
做爲一個總體帶到前臺。Task
中的Activity
的順序一般是不能改變的,只能經過出棧入棧的方式來增長或移除。
AMS
中使用ActivityStack
來管理Task
,它管理的Task
都存放在成員變量mTaskHistory
中,定義以下:
class ActivityStack{
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
}
複製代碼
mTaskHistory
是一個列表,儲存的是TaskRecord
對象。TaskRecord
對象表示一個Task
,它的成員變量mActivities
也是一個列表,儲存了該Task
中全部的ActivityRecord
對象。mActivities
的定義以下:
class TaskRecord{
final ArrayList<ActivityRecord> mActivities;
}
複製代碼
那麼,如何才能開始一個新的Task
呢?
Intent
中定義了一個標誌FLAG_ACTIVITY_NEW_TASK
,在startActivity()
的Intent
參數中加入該標誌就能開啓一個新的Task
affinity
的Task
存在,並不會再啓動一個Task
,而是將舊的Task
帶到前臺那麼,affinity
在哪裏定義的呢?
affinity
的意思是親和度,是經過<activity>
標籤的android:taskAffinity
屬性來定義的FLAG_ACTIVITY_NEW_TASK
啓動一個Activity
時,這個Activity
的taskAffinity
屬性中的字符串就會成爲Task
的affinity
Task
的Activity
,即便它們的taskAffinity
屬性定義了一個不一樣的字符串,也不會改變Task
已有的affinity
<activity>
標籤中沒有指定android:taskAffinity
屬性,這個Activity
會繼承<application>
標籤的android:taskAffinity
屬性<application>
標籤的android:taskAffinity
屬性也沒有定義,將會使用應用包名做爲缺省值
Activity
,即便使用了FLAG_ACTIVITY_NEW_TASK
標誌也不必定會啓動一個新的Task
Activity
定義了不一樣的taskAffinity
屬性LaunchMode
Activity
的啓動模式隱含的是Activity
對象的複用問題,關於啓動模式官網的介紹也很詳細:官方傳送門
當啓動一個Activity
時,若是系統的後臺Task
中已經有一個該Activity
的實例存在了,系統是建立一個新的Activity
仍是將已經存在的Activity
切換到前臺呢?
答案是都有可能,有多種因素能夠影響結果。包括Activity
的屬性值以及Intent
中指定的標誌
咱們先看下Activity
的屬性launchMode
會有哪些影響:
standard
模式:默認。
standard
模式下的Activity
每次啓動時都會建立該Activity
的實例對象Task
中能夠同時存在該Activity
的多個實例Activity
的多個實例能夠出如今多個Task
棧中singleTop
模式
Task
的頂部已存在該Activity
實例,則系統會經過調用該實例的onNewIntent()
方法向其傳送Intent
,而非建立新的Activity
實例。standard
模式同樣建立新的實例對象singleTask
模式
singleTask
模式的Activity
具備系統惟一性,只能在系統中建立該Activity
的一個實例對象singleTask
模式的Activity
時,若是系統中已經存在該Activity
的實例對象,則將其所在的Task
中排在它前面的Activity
都彈出棧,將該Activity
帶到棧頂,並調用其onNewIntent()
方法傳遞新的Intent
對象Activity
的實例對象,則會建立一個該Activity
的實例對象
Activity
的taskAffinity
屬性值和當前Task
的affinity
值相同,它會加入當前的Task
中Activity
的Intent
中沒有指定FLAG_ACTIVITY_NEW_TASK
標誌,也會啓動新的Task
,並將Activity
至於其中singleInstance
模式
singleInstance
模式的Activity一樣具備系統惟一性,系統中只有該Activity的一個實例對象Activity
啓動到包含該Activity
實例的Task
中Activity
始終是其Task
中的惟一Activity
一般狀況下,一個Activity
建立出來後,會停留在某個Task
中,直到它被銷燬
Activity
的allowTaskReparenting
屬性設置爲true
,該Activity
能夠在不一樣的Task
之間轉移Activity
的Intent
中設置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
標誌時才起做用除了上面介紹的內容,Activity
和Task
的工做邏輯你們能夠參考官網:任務和返回堆棧
好比,下面部分提到的技巧就很重要(摘抄自官網):
只有當 Activity 具備 ACTION_MAIN 和 CATEGORY_LAUNCHER 過濾器時,才應使用 "singleTask" 和 "singleInstance" 這兩種啓動模式,它們會將 Activity 標記爲始終啓動任務。好比,能夠想象一下,若是缺乏該過濾器會發生什麼狀況:intent 會啓動 "singleTask" Activity,隨之啓動新任務,用戶花了一些時間在該任務上。而後,用戶按主屏幕按鈕。此時,該任務會轉到後臺,再也不可見。如今,用戶沒法返回到該任務,由於它未顯示在應用啓動器中。
ClientTransactionHandler
的做用
ClientTransactionHandler
是在Android 9.0
上出現的,用來串聯起AMS
和Activity
的整個生命週期管理的類,很重要
咱們已經知道應用的入口是ActivityThread
類的main()
函數,仔細看下類結構的話會發現要ActivityThread
繼承了一個特殊的類。定義以下
public final class ActivityThread extends ClientTransactionHandler {
...
}
複製代碼
能夠看到ActivityThread
繼承了ClientTransactionHandler
類。這個類是在Android 9.0
加入的,關鍵定義以下:
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
......
public abstract void handleDestroyActivity(...);
public abstract void handlePauseActivity(...);
public abstract void handleResumeActivity(...);
public abstract void handleStopActivity(...);
......
public abstract Activity handleLaunchActivity(...);
public abstract void handleStartActivity(...);
......
public abstract void handleNewIntent(...);
......
}
複製代碼
類中定義了和聲明週期有關的方法,機智的咱們能夠猜到,AMS
後面生命週期的回調控制應該就是經過它來實現的,相關類繼承關係以下:
能夠Android
把Activity
相關的生命週期要作的事情抽象了出來,在上面定義的類中,真正業務實現包括:
LaunchActivityItem
就是要執行launch activity
任務resume activity
則是經過ResumeActivityItem
實現pause activity
則是經過PauseActivityItem
實現stop activity
則是經過StopActivityItem
實現destroy activity
則是經過DestoryActivityItem
實現ClientTransaction
的調用邏輯咱們看下整個調用流程: 在ActivityThread
中的ApplicationThread
類有一個scheduleTransaction()
方法,
ApplicationThread
類是一個Binder
服務類,AMS
會做爲client
調用這個服務類,固然也就能夠調用它的scheduleTransaction()
方法
scheduleTransaction()
方法內容以下:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
複製代碼
調用的是ActivityThread
的scheduleTransaction()
方法,也就是ClientTransactionHandler
類的scheduleTransaction()
方法,方法以下:
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
複製代碼
發送了一個EXECUTE_TRANSACTION
消息給ActivityThread
的Handler
實現類H
,消息處理以下:
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
複製代碼
消息處理中使用了mTransactionExecutor.execute()
,不出意外,執行邏輯確定在TransactionExecutor
中了,咱們看下:
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null) {
return;
}
......
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
......
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
......
}
}
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
......
// 很重要的一個方法
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
複製代碼
能夠看到,最後分別在executeCallbacks()
和executeLifecycleState()
兩個方中執行了item.execute()
和lifecycleItem.execute()
兩個方法
executeCallbacks()
和executeLifecycleState()
目的分別是幹什麼呢?結合類關係圖咱們能夠這樣推斷:
executeCallbacks()
遍歷執行的是ClientTransaction
類中List<ClientTransactionItem> mActivityCallbacks
集合中的元素
ClientTransactionItem
類的直接子類實現只有LaunchActivityItem
類executeCallbacks()
主要執行的是launch activity
的通知操做executeLifecycleState()
執行的是ClientTransaction
類中的ActivityLifecycleItem mLifecycleStateRequest
mLifecycleStateRequest
被稱爲final state
resume activity
、pasue activity
、stop activity
、destory activity
都在這裏瞭解完調用流程會發現,實現類中並無StartActivityItem
,爲何呢?那怎麼調用onStart()
函數呢?
核心就在cycleToPath()
函數身上
TransactionExecutor.cycleToPath()
針對
Activity
的生命週期,Android
並無定義出全部的*ActivityItem
類,例如StartActivityItem
就並不存在,那麼怎麼去執行這個start
階段的函數呢?
請留意類圖中ActivityLifecycleItem
有關生命週期的常量定義,Android
在這裏經過cycleToPath()
採用了一種比較取巧的操做,核心邏輯就是:
Activity
的final state
Activity
的當前狀態去計算過程當中須要的狀態,並保存到集合中以文章後面的realStartActivityLocked()
方法爲例
LaunchActivityItem
類型的對象添加到callback
中
TransactionExecutor
會先執行LaunchActivityItem
類Activity
進入到ON_CREATE
狀態final state
爲ResumeActivityItem
TransactionExecutor
經過cycleToPath()
計算當前狀態與final state
的差別ON_CREATE
狀態,final state
爲ON_RESUME
TransactionExecutor
經過幫助類的getLifecyclePath
方法將二者之間缺失的狀態整理到集合中performLifecycleSequence()
循環處理performLifecycleSequence()
方法以下:
private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(...);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(...);
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(...);
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(...);
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(...);
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(...);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
複製代碼
PauseActivityItem
的調用分析以PauseActivityItem
類爲例,咱們看看具體的執行邏輯:
public class PauseActivityItem extends ActivityLifecycleItem {
......
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
......
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
......
}
}
複製代碼
執行的是ClientTransactionHandler
抽象類,其實也就是ActivityThread
類的handlePauseActivity()
方法。
handlePauseActivity()
方法調用了ActivityThread
類的performPauseActivity()
方法,最後調用到的是performPauseActivityIfNeeded()
方法,代碼以下:
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
......
mInstrumentation.callActivityOnPause(r.activity);
......
}
複製代碼
執行的是Instrumentation
類的callActivityOnPause()
方法,內容以下:
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
複製代碼
很簡潔,繼續查看:
public class Activity{
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
mResumed = false;
......
}
}
複製代碼
有木有!有木有!onPause();
終於調用到了。。。。。。
咱們已經從應用端找到了調用的流程,可是,對於AMS
來講它是怎麼觸發的呢?
接下來,咱們分析下Activity
的啓動,在Activity
啓動的過程咱們就能夠找到AMS
觸發聲明週期的例子
Activity
研究
Activity
生命週期的調用細節,咱們仍是得從最熟悉的地方入手,也就是經常使用的Activity
對象的startActivity (Intent intent)
方法
Activty.startActivty()
跟蹤startActivity (Intent intent)
方法,發現調用關係以下:
class Activity{
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(...) {
......
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
......
}
}
class Instrumentation{
public ActivityResult execStartActivity(...) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(...);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
}
class ActivityManagerService{
public final int startActivity(...) {
return startActivityAsUser(...);
}
public final int startActivityAsUser(...) {
......
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
...
.execute();
}
}
複製代碼
咱們看到最後是調用的是AMS
的startActivityAsUser
方法。跟蹤startActivityAsUser
方法的調用過程就會發現最後執行的是ActivityStarter
類的execute()
方法來執行Activity
的啓動,相關代碼以下:
class ActivityStater{
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(...);
} else {
return startActivity(...);
}
} finally {
onExecutionComplete();
}
}
}
複製代碼
咱們看到execute()
有兩個啓動Activity
的方法,接下來咱們以startActivityMayWait()
方法繼續分析,由於最後也會走到startActivity()
中。
ActivityStarter.startActivityMayWait()
簡要代碼以下:
private int startActivityMayWait(...) {
......
// 獲取要啓動的 Activity 的信息
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService) {
......
int res = startActivity(caller, ...);
......
if (outResult != null) { // 須要返回結果
outResult.result = res;
final ActivityRecord r = outRecord[0];
switch(res) {
case START_SUCCESS: {
// 添加到特定集合中
mSupervisor.mWaitingActivityLaunched.add(outResult);
do {
try {
// 等待應用進程中的 Activity 啓動完成
mService.wait();
} catch (InterruptedException e) {
}
} while (outResult.result != START_TASK_TO_FRONT
&& !outResult.timeout && outResult.who == null);
......
break;
}
......
}
}
return res;
}
}
複製代碼
startActivityMayWait()
方法的流程以下:
resolveActivity()
方法來獲取要啓動的Activity
的信息Activity
的信息後,繼續調用startActivity()
方法來繼續啓動Activity
Activity
的應用須要獲取返回結果,則調用mService
對象的wait()
方法掛起線程等待啓動的結果接下來就是調用ActivityStarter
的startActivity()
方法的代碼,咱們看下部分細節:
private int startActivity(IApplicationThread caller, ...) {
int err = ActivityManager.START_SUCCESS;
......
if (caller != null) {
// 獲取啓動Activity的進程的信息
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
err = ActivityManager.START_PERMISSION_DENIED;
}
}
final int userId = aInfo != null && aInfo.applicationInfo != null
? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
......// 省略不少錯誤檢查
// 檢查調用者的相關權限
boolean abort = !mSupervisor.checkStartAnyActivityPermission(...);
// 檢查 Intent 防火牆是否屏蔽了該 Intent
abort |= !mService.mIntentFirewall.checkStartActivity(...);
......
if (mService.mController != null) {
try {
// 將 Activity 啓動的消息通知監聽系統Activity變更的接口 IActivityControler
Intent watchIntent = intent.cloneFilter();
abort |= !mService.mController.activityStarting(watchIntent,
aInfo.applicationInfo.packageName);
} catch (RemoteException e) {
mService.mController = null;
}
}
......
if (abort) {
......// 若是 abort 爲true,直接退出
return START_ABORTED;
}
......
// 建立 ActivityRecord 對象
ActivityRecord r = new ActivityRecord(...);
if (outActivity != null) {
outActivity[0] = r;
}
......
// 當前用戶正在操做的 ActivityStack
final ActivityStack stack = mSupervisor.mFocusedStack;
// 針對常常切換進程的狀況,檢查調用者是否有權限進行進程切換
if (voiceSession == null && (stack.getResumedActivity() == null
|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
realCallingPid, realCallingUid, "Activity start")) {
// 對於不能切換進程的狀況,把 Activity 信息放入 mPendingActivityLaunches 列表中
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
sourceRecord, startFlags, stack, callerApp));
ActivityOptions.abort(checkedOptions);
return ActivityManager.START_SWITCHES_CANCELED;
}
}
if (mService.mDidAppSwitch) {
mService.mAppSwitchesAllowedTime = 0;
} else {
mService.mDidAppSwitch = true;// 打開開關,容許進程間切換
}
// 啓動掛起等待的 Activity,其實就是逐個啓動 mPendingActivityLaunches 列表中的 Activity。
// 最後也是調用了 startActivity
// 我的理解,大多數狀況下 mPendingActivityLaunches 列表應該是空的吧
mController.doPendingActivityLaunches(false);
......
// 調用startActivity另外一個重載方法,第一個參數爲 ActivityRecord
return startActivity(r, ...);
}
private int startActivity(final ActivityRecord r, ...) {
int result = START_CANCELED;
......
result = startActivityUnchecked(r, ...);
......
return result;
}
複製代碼
這裏其實不用記錄太多細節,重要的是瞭解啓動Activity
方法的調用流程,這裏最後調用的是startActivityUnchecked()
方法,咱們來繼續看下。
ActivityStarter.startActivityUnchecked()
方法以下:
private int startActivityUnchecked(final ActivityRecord r, ...) {
// 初始化環境和lunchModeFlags
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
computeLaunchingTaskFlags();
computeSourceStack();
mIntent.setFlags(mLaunchFlags);
// 判斷 Activity 是否須要插入新的 Task,如下狀況 reusedActivity 不爲空
// 1.設置了FLAG_ACTIVITY_NEW_TASK:
// 2.啓動模式爲singleTask:
// 3.啓動模式爲singleInstance
ActivityRecord reusedActivity = getReusableIntentActivity();
......
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
if (dontStart) { // 不須要啓動的狀況
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
......
deliverNewIntent(top);
......
return START_DELIVERED_TO_TOP;
}
boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// 判斷當前 Activity 是否須要一個新的 Task
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
......
// 啓動 Activity
// startActivityLocked 這裏主要是將 ActivityRecord 對象加入到 Task 的頂部
// 同時將 Task 添加到 mTaskHistory 的頂部
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
// 利用 WindowManager 使 Activity 可見
if (mDoResume) {
final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mService.mWindowManager.executeAppTransition(); // 此處應該是執行應用間的切換動畫
} else {
.......
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
}
......
return START_SUCCESS;
}
複製代碼
startActivityUnchecked()
方法主要是經過Intent
的標誌和Activity
的屬性來肯定Activity
的Task
,而後將其調整至棧頂,細節咱們先略過,須要重點關注的方法是mSupervisor.resumeFocusedStackTopActivityLocked()
方法的調用。跟蹤調用就會發現,最後執行的是ActivityStack
類的resumeTopActivityInnerLocked()
方法
ActivityStack.resumeTopActivityInnerLocked()
咱們前面已經知道
resumeFocusedStackTopActivityLocked()
方法最終會調用ActivityStack
類的resumeTopActivityInnerLocked()
方法。
resumeTopActivityInnerLocked()
方法主要的做用是將位於棧頂的Activity
顯示出來,不過在此以前,舊的Activity
(變量mResumedActivity
引用的就是)還顯示在屏幕上。方法內容以下:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
}
// 從要 mTaskHistory 中查找要啓動的 Activity
// 這裏這樣作應該是由於前面已經將 Activity 放入堆棧中了
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
final boolean hasRunningActivity = next != null;
......
if (!hasRunningActivity) {
// There are no activities left in the stack, let's look somewhere else.
return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
}
next.delayedResume = false;
// 若是當前顯示的 Activity 就是要啓動的 Activity,直接返回
if (mResumedActivity == next && next.isState(RESUMED)
&& mStackSupervisor.allResumedActivitiesComplete()) {
executeAppTransition(options);
return false;
}
// 若是正在休眠或者關機,直接返回
if (shouldSleepOrShutDownActivities()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
executeAppTransition(options);
return false;
}
// user 狀態檢查
if (!mService.mUserController.hasStartedUserState(next.userId)) {
return false;
}
// 將要啓動的 Activity 從相關隊列中移除
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
// 檢查是否有正在 Pause 的 Activity
if (!mStackSupervisor.allPausedActivitiesComplete()) {
return false;
}
// 設置要啓動的 applicationInfo
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
......
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
// 暫停當前 Activity
// startPausingLocked() 中便會觸發 舊Activity 的 onPause() 操做
pausing |= startPausingLocked(userLeaving, false, next, false);
}
......
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
// 若是 Activity 所在的應用已經存在,只須要把 Activity 顯示出來
......
synchronized(mWindowManager.getWindowManagerLock()) {
// This activity is now becoming visible.
if (!next.visible || next.stopped || lastActivityTranslucent) {
next.setVisibility(true);
}
......
try {
final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
next.appToken);
......
// 若是當前 Activity 還有等待返回的結果,添加 ActivityResultItem,
// 其中會執行 onActivityResult 回調
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
// 添加 NewIntentItem,其中會執行 onNewIntent
if (next.newIntents != null) {
transaction.addCallback(NewIntentItem.obtain(next.newIntents,
false /* andPause */));
}
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.repProcState,
mService.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
......
} catch (Exception e) {
// Whoops, need to restart this activity!
......
mStackSupervisor.startSpecificActivityLocked(next, true, false);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
}
......
} else {
// Whoops, need to restart this activity!
......
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
......
return true;
}
複製代碼
resumeTopActivityInnerLocked()
代碼比較長做了精簡,核心邏輯以下:
startPausingLocked()
暫停舊的Activity
,startPausingLocked()
方法以下: final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) {
......
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
......
}
複製代碼
ClientTransaction
呼應上了,嘿嘿Activity
所在的應用已經啓動,對Activity
進行顯示處理,建立ResumeActivityItem
進行生命週期通知
Activity
對象的onResume()
方法的執行startSpecificActivityLocked()
方法繼續處理,方法以下: void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 獲取 Activity 對應的進程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
if (app != null && app.thread != null) {
try {
......
// 若是應用進程已經存在的狀況,執行 realStartActivityLocked()
// andResume = true
realStartActivityLocked(r, app, andResume, checkConfig);
// 而後返回
return;
} catch (RemoteException e) {
}
}
// Activity 對應的進程爲空,經過 AMS 的 startProcessLocked() 建立新的進程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
複製代碼
realStartActivityLocked()
,就算是從新啓動進程的狀況,最後執行的也是realStartActivityLocked()
ActivityStackSupervisor.realStartActivityLocked()
對於realStartActivityLocked()
方法,咱們簡單看下和生命週期相關的內容:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
......
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
// 添加 LaunchActivityItem,這個會觸發 onCreate 方法
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), ...);
// 設置最終狀態,resume 仍是 pause
final ActivityLifecycleItem lifecycleItem;
// 根據前面的調用參數能夠肯定,andResume = true
if (andResume) {
// 設置最終狀態爲 ON_RESUME
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
return true;
}
複製代碼
方法中添加了LaunchActivityItem
和ResumeActivityItem
類的對象,並調用了scheduleTransaction()
方法。
LaunchActivityItem
屬於比較複雜的調用邏輯
以LaunchActivityItem
類爲例,咱們來看跟蹤下調用關係:
public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
......
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
......
}
}
複製代碼
調用的是ActivityThread
中handleLaunchActivity()
的方法:
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
......
final Activity a = performLaunchActivity(r, customIntent);
......
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
......
} catch (Exception e) {
...
}
try {
......
if (activity != null) {
......
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
// 將狀態設置爲 ON_CREATE
r.setState(ON_CREATE);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
......
}
return activity;
}
複製代碼
調用的是Instrumentation.callActivityOnCreate()
方法,內容以下:
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
複製代碼
最後經過是調用的Activity.performCreate()
方法:
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
......
}
複製代碼
到這裏,LaunchActivityItem
的邏輯就結束了,也執行完了onCreate()
回調,狀態設置爲了ON_CREATE
。
可是因爲realStartActivityLocked()
中設置的最終狀態爲ON_RESUME
,當前Activity
的狀態不是最終狀態,因此TransactionExecutor
還會繼續執行。