本文是個人 AOSP 系列 第六篇文章,往期目錄以下:java
Java 世界的盤古和女媧 —— Zygoteandroid
Zygote家的大兒子 —— SystemServergit
Android 世界中,誰喊醒了 Zygote ?github
一路從 Zygote 說到 SystemServer ,從 AMS 的啓動流程 說到 應用進程的建立,再到上一期的 Activity 啓動流程,今天準備來講說你們耳熟能詳的 Activity 的生命週期。關於生命週期的基礎知識,官網上的這篇文章 瞭解 Activity 的生命週期 已經做了詳細介紹。在本文中,我會從源碼角度來切入生命週期的調用流程。微信
提到 Android 官網的 文檔 部分,我想多說一句。不論是新知識點,仍是你已經掌握的內容,這裏都是一份絕佳的資料庫。我如今每複習一個知識點,都會去重讀一遍官網文檔,總能有不同的收貨,文末也貼出了個人閱讀筆記。網絡
再回到本文來,其實若是有仔細閱讀上一篇文章 庖丁解牛Activity 啓動流程 的話,裏面已經較爲詳細的介紹了生命週期的調用流程。只是上篇文章閱讀體驗的確不怎麼好,因此這裏把 Activity 的生命週期 單獨拎出來講一說。app
首先來看下 Google 給出的 Activity 經典生命週期圖:async
這張圖應該沒什麼好說的了,你們確定瞭如指掌。可是你瞭解每一個生命週期背後的調動流程嗎?
經過上篇文章咱們都知道了 Activity 的啓動由應用進程發起,經過 Binder 調用 AMS 完成,那麼 AMS 所在進程是如何回調到到應用進程的生命週期方法的呢?
其實圖中的每個生命週期方法的調用流程都是同一個套路,大同小異,先搞清楚這個套路,其餘問題就迎刃而解了。
爲了方便講解,咱們以 Activity 最早被調用的生命週期 onCreate()
爲例。
回顧 Activity 的啓動流程,最後會調用到 ActivityStackSupervisor
的 realStartActivityLocked()
方法。
> ActivityStackSupervisor.java final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
......
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
// 1. 添加 LaunchActivityItem callback
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
// 2. 設置生命週期狀態
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 3. 調用 ClientLifecycleManager.scheduleTransaction()
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
return true;
}
複製代碼
已省略大量無關代碼。
上述代碼中構建了一個 ClientTransaction
對象,分別調用了它的 addCallback()
和 setLifecycleStateRequest()
方法,最後調動 schchueduleTransaction
執行構造的 ClientTransaction
對象,分別對應註釋的 1 、2 、3 處。下面來看一下這三個方法。
> ClientTransaction.java public void addCallback(ClientTransactionItem activityCallback) {
if (mActivityCallbacks == null) {
mActivityCallbacks = new ArrayList<>();
}
mActivityCallbacks.add(activityCallback);
}
複製代碼
mActivityCallbacks
是元素類型爲 ClientTransactionItem
的集合。addCallback()
傳入的參數是 LaunchActivityItem
, 正是 ClientTransactionItem
的實現類。
> ClientTransaction.java public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
mLifecycleStateRequest = stateRequest;
}
複製代碼
mLifecycleStateRequest
表示當前的 ClientTransaction 執行以後應該處於的最終生命週期狀態。
註釋 3 處 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
,mService.getLifecycleManager()
返回的是 ClientLifecycleManager
對象,是 Android 9.0 新增的輔助處理生命週期的類,以往的源碼中是沒有的。看一下它的 scheduleTransaction()
方法。
> ClientLifecycleManager.java void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient(); // -> ApplicationThread
transaction.schedule(); // ClientTransaction
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
複製代碼
調用了 ClientTransaction
的 schedule()
方法。
> ClientTransaction.java public void schedule() throws RemoteException {
// 調用 ActivityThread.ApplicationThread.scheduleTransaction()
mClient.scheduleTransaction(this);
}
複製代碼
首先明確一點,到目前爲止的方法調用都處於 AMS 所在進程,並非咱們的應用進程。那麼 mClient
是什麼呢?java
private IApplicationThread mClient;
複製代碼
IApplicationThread
是極其重要的一個 Binder 接口,它維護了應用進程和 AMS 的之間的通信。這個 mClient
就是應用進程在 AMS 進程中的代理對象,AMS 經過 mClient
來指揮應用進程。
mClient
只是 AMS 進程中的一個 "傀儡" ,它的真身是 ActivityThread.ApplicationThread
。
private class ApplicationThread extends IApplicationThread.Stub {
......
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
// 這裏調用的是父類 ClientTransactionHandler 的 scheduleTransaction() 方法
ActivityThread.this.scheduleTransaction(transaction);
}
......
}
複製代碼
ActivityThread
並無 scheduleTransaction()
方法,因此調用的是其父類 ClientTransactionHandler
的相應方法。
> ClientTransactionHandler.java void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);java
// sendMessage() 方法在 ActivityThread類中實現
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
複製代碼
ClientTransactionHandler
是一個抽象類,sendMeschusage()
也是一個抽象方法,其具體實如今 ActivityThread
類中,記住其參數 ActivityThread.H.EXECUTE_TRANSACTION
。
> ActivityThread.java private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);java
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);chu
}
mH.sendMessage(msg);
}
複製代碼
其中的 mH
是 ActivityThread 的內部類 H
,是一個 Handler 對象。咱們都知道 Handler 是用於線程間通信的,那麼這裏是哪兩個線程之間呢?AMS 經過 Binder 調用應用進程的對應方法,執行的是應用進程的 Binder 線程,而真正須要回調生命週期的是 主線程 ,因此這裏進行通信的就是 Binder 線程 和 主線程。
class H extends Handler {
public void handleMessage(Message msg) {
......
case EXECUTE_TRANSACTION:chu
final ClientTransaction transaction = (ClientTransaction) msg.obj;
// 執行 TransactionExecutor.execute()
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
......
}
}
複製代碼
獲取到 AMS 發送過來的 ClientTransaction
對象,調用 TransactionExecutor
的 execute()
方法來執行這次事務。
> TransactionExecutor.java public void execute(ClientTransaction transaction) { clientTransaction.setLifecycleStateRequest(lifecycleItem);
executeCallbacks(transaction);
// 執行生命週期狀態
executeLifecycleState(transaction);
}
複製代碼
看到 execute() 中的兩個方法,你應該有種似曾相識的感受。回到文章開頭處 ActivityStackSupervisor
的 realStartActivityLocked()
方法 :
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
......
// 1. addCallback()
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new ...
// 2. setLifecycleStateRequest
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 3. 調用 ClientLifecycleManager.scheduleTransaction()
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
return true;
}
複製代碼
addCallback() >>> executeCallbacks()
setLifecycleStateRequest >>> executeLifecycleState()
executeCallbacks()
會執行 addCallback()
方法添加的生命週期回調。當前添加的是 LaunchActivityItem
。
executeLifecycleState()
方法會將當前生命週期同步到 setLifecycleStateRequest()
方法設置的生命週期狀態。當前設置的是 ResumeActivityItem
。
從源碼來看看這兩個方法是如何執行的。
> TransactionExecutor.java public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
......
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
......
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
......
}
}
複製代碼
獲取全部的 callback 並循環調用 execute()
和 postExecute()
方法。這裏的 calkback 只有一個元素 LaunchActivityItem
。
public class LaunchActivityItem extends ClientTransactionItem {
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
// 調用 ActivityThread.handleLaunchActivity()
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
}
複製代碼
構建了 ActivityClientRecord
對象,接着調用 ActivityThread
的 handleLaunchActivity()
方法。
> ActivityThread.java
@Override
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
......
// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);
WindowManagerGlobal.initialize();
final Activity a = performLaunchActivity(r, customIntent);activityIdleInternalLocked
......
return a;
}
複製代碼
performLaunchActivity()
上篇文章已經詳細介紹過,下面代碼中僅保留生命週期相關代碼。
> ActivityThread.java private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
// 獲取 Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
java.lang.ClassLoader cl = appContext.getClassLoader();
// 反射建立 Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// 獲取 Application系統永遠不會直接終止 Activity 以釋放內存,而是會終止 Activity 所在的進程。系統不只會銷燬 Activity,還會銷燬在該進程中運行的全部其餘內容。
if (activity != null) {activityIdleInternalLocked
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embedded // 獲取 Context
CID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
// 設置主題
activity.setTheme(theme);
}
activity.mCalled = false;
// 執行 onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
}
r.setState(ON_CREATE);
mActivities.put(r.token, r);
return activity;
}
複製代碼
重點關注 mInstrumentation.callActivityOnCreate()
。Instrumentation
是個很重要的類,它在 Activity 的啓動,生命週期管理中都承擔了重要的角色。
> Instrumentation.java public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
複製代碼
> Activity.java final void performCreate(Bundle icicle, PersistableBundle persistentState) {
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
// 執行 onCreate()
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
......
}
複製代碼
最終終於執行到了 Activity 的 onCreate() 方法,executeCallbacks()
方法也就到此結束了。固然,onCreate()
並非一個長久存在的狀態,那麼如何過渡到下一個生命週期呢?來看看 executeLifecycleState()
方法。
> TransactionExecutor.java private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
......
// Cycle to the state right before the final requested state.
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
複製代碼
executeLifecycleState()
方法的參數是 ResumeActivityItem
,方法體內直接調用其 execute()
方法。
> ResumeActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
}
複製代碼
能夠看到和 onCreate()
的套路是如出一轍的,調用 ActivityThread.handleResumeActivity()
,接着是 Instrumentation.callActivityOnResume()
,最後回調 Activity.onResume()
。
一個生命週期又完成了,onResume()
是一個相對能夠長期存在的生命週期狀態。
等等,有沒有感受哪裏不對勁?onStart()
哪裏去了?
正常的生命週期流程應該是 onCreate() -> onStart() -> onResume()
,可是代碼中好像又沒有顯示調用。實際上是在 executeLifecycleState()
中的 cycleToPath()
方法中作了生命週期的同步。簡單說就是,當前處於 onCreate()
狀態,setLifecycleState()
設置的 final state 是 onResume() ,就須要執行 onCreate 到 onResume 之間的狀態,即 onStart()
。下面簡單看下源碼。
> TransactionExecutor.java private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState) {
final int start = r.getLifecycleState();
log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path);
}
複製代碼
getLifecyclePath()
方法就是根據 start
和 finish
計算出中間的生命週期路徑。這裏計算出來就是 ON_START
。
> TransactionExecutor.java private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
log("Transitioning to state: " + state);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");> TransactionExecutor.java
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
複製代碼
找到 ON_START
分支,調用了 ActivityThread.handleStartActivity()
方法,又是同樣的套路了,這裏就再也不贅述了。
依次類推,ActivityThread
中應該有以下方法:
handleLaunchActivity()
handleStartActivity()
handleResumeActivity()
handlePauseActivity()
handleStopActivity()
handleDestroyActivity()
複製代碼
寫到這,已經分析完了 onCreate()
、onStart()
、onResume()
這三個生命週期的調用時機和流程,剩下的 onPause
、onStop
、onDestroy()
就放到下篇文章再說吧。
給你們分享一下我閱讀 Activity 生命週期相關官方文檔的一些筆記。
onCreate
您必須實現此回調,其在系統首次建立 Activity 時觸發。Activity 會在建立後進入已建立狀態。該邏輯在 Activity 的整個生命週期中只應發生一次。
onStart
當 Activity 進入「已開始」狀態時,系統會調用此回調。onStart() 調用使 Activity 對用戶可見,由於應用會爲 Activity 進入前臺並支持交互作準備。
onStart() 方法會很是快速地完成,而且與「已建立」狀態同樣,Activity 不會一直處於「已開始」狀態。一旦此回調結束,Activity 便會進入已恢復狀態,系統將調用 onResume() 方法。
onResume
Activity 會在進入「已恢復」狀態時來到前臺,而後系統調用 onResume() 回調。這是應用與用戶交互的狀態。應用會一直保持這種狀態,直到某些事件發生,讓焦點遠離應用。
onPause
系統將此方法視爲用戶正在離開您的 Activity 的第一個標誌(儘管這並不老是意味着活動正在遭到銷燬);此方法表示 Activity 再也不位於前臺(儘管若是用戶處於多窗口模式,Activity 仍然可見)。
onPause() 執行很是簡單,並且不必定要有足夠的時間來執行保存操做。所以,您不該使用 onPause() 來保存應用或用戶數據、進行網絡調用,或執行數據庫事務。由於在該方法完成以前,此類工做可能沒法完成。
完成 onPause() 方法並不意味着 Activity 離開「已暫停」狀態。相反,Activity 會保持此狀態,直到其恢復或變成對用戶徹底不可見。
onStop
若是您的 Activity 再也不對用戶可見,則說明其已進入已中止狀態,所以系統將調用 onStop() 回調。
在 onStop() 方法中,應用應釋放或調整應用對用戶不可見時的無用資源。
您還應該使用 onStop() 執行 CPU 相對密集的關閉操做。
進入「已中止」狀態後,Activity 要麼返回與用戶交互,要麼結束運行並消失。
onDestroy
銷燬 Ativity 以前,系統會先調用 onDestroy()。系統調用此回調的緣由以下:
系統永遠不會直接終止 Activity 以釋放內存,而是會終止 Activity 所在的進程。系統不只會銷燬 Activity,還會銷燬在該進程中運行的全部其餘內容。
目前爲止,咱們已經深刻探討了 Activity 的啓動流程,Activity 的生命週期流程。可是關於 Activity 的知識點實在是有點多。
Activity 是什麼?Activity 由什麼組成?Activity 是如何顯示到屏幕上的?
目測還能夠再爲 Activity 寫四五篇文章,敬請期待。
---- 分割線
買了一個服務器,準備用 Halo 搭建我的博客,好好整理一下以前寫過的各個系列的文章。求推薦域名! 求推薦域名! 求推薦域名!
文章首發微信公衆號:
秉心說
, 專一 Kotlin、 Java 、 Android 原創知識分享,AOSP 源碼解析。更多最新原創文章,掃碼關注我吧!