本文是我的 AOSP 系列 第六篇文章,往期目录如下:
一路从 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 写四五篇文章,敬请期待。
—- 分割线
买了一个服务器,准备用 Halo 搭建个人博客,好好整理一下之前写过的各个系列的文章。求推荐域名! 求推荐域名! 求推荐域名!
文章首发微信公众号:
秉心说TM
, 专注 Kotlin、 Java 、 Android 原创知识分享,AOSP 源码解析。更多最新原创文章,扫码关注我吧!
今天的文章从源码看 Activity 生命周期(上篇)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19432.html