一路从 Zygote 说到 SystemServer ,从 AMS 的启动流程 说到 应用进程的创建,再到上一期的 Activity 启动流程,今天准备来说说大家耳熟能详的 Activity 的生命周期。关于生命周期的基础知识,官网上的这篇文章 了解 Activity 的生命周期 已经作了详细介绍。在本文中,我会从源码角度来切入生命周期的调用流程。
提到 Android 官网的 文档 部分,我想多说一句。不管是新知识点,还是你已经掌握的内容,这里都是一份绝佳的资料库。我现在每复习一个知识点,都会去重读一遍官网文档,总能有不一样的收货,文末也贴出了我的阅读笔记。
再回到本文来,其实如果有仔细阅读上一篇文章 庖丁解牛Activity 启动流程 的话,里面已经较为详细的介绍了生命周期的调用流程。只是上篇文章阅读体验的确不怎么好,所以这里把 Activity 的生命周期 单独拎出来说一说。
首先来看下 Google 给出的 Activity 经典生命周期图:
这张图应该没什么好说的了,大家肯定了如指掌。但是你了解每个生命周期背后的调动流程吗?
通过上篇文章我们都知道了 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.addCallback()
> ClientTransaction.java public void addCallback(ClientTransactionItem activityCallback) { if (mActivityCallbacks == null) { mActivityCallbacks = new ArrayList<>(); } mActivityCallbacks.add(activityCallback); } 复制代码
mActivityCallbacks
是元素类型为 ClientTransactionItem
的集合。addCallback()
传入的参数是 LaunchActivityItem
, 正是 ClientTransactionItem
的实现类。
ClientTransaction.setLifecycleStateRequest()
> ClientTransaction.java public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) { mLifecycleStateRequest = stateRequest; } 复制代码
mLifecycleStateRequest
表示当前的 ClientTransaction 执行之后应该处于的最终生命周期状态。
ClientLifecycleManager.scheduleTransaction()
注释 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.executeCallbacks()
> 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.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()
是一个相对可以长期存在的生命周期状态。
TransactionExecutor.cycleToPath()
等等,有没有感觉哪里不对劲?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 调用 finish()
- 由于配置变更(例如设备旋转或多窗口模式),系统暂时销毁 Activity
系统永远不会直接终止 Activity 以释放内存,而是会终止 Activity 所在的进程。系统不仅会销毁 Activity,还会销毁在该进程中运行的所有其他内容。
最后
目前为止,我们已经深入探讨了 Activity 的启动流程,Activity 的生命周期流程。但是关于 Activity 的知识点实在是有点多。
Activity 是什么?Activity 由什么组成?Activity 是如何显示到屏幕上的?
目测还可以再为 Activity 写四五篇文章,敬请期待。