非原创,整理
onStop方法什么时候被调用
DestroyActivityItem的execute和postExecute方法是在TransactionExecutor的executeLifecycleState方法中调用的:
// in TransactionExecutor.java
private void executeLifecycleState(ClientTransaction transaction) {
// Cycle to the state right before the final requested state.
//根据Activity当前的状态和最终要到达的状态,计算中间需要经过哪些步骤
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
关键代码是cycleToPath(),只要稍微一跟踪就可以知道在Pause和Destroy之间会执行Stop了,这个流程简单没有其他分支。
onStop和onDestroy回调为什么会延时
调用finish后,回调onStop和onDestroy之间的整个正常流程。这中间经历了多次App侧和AMS侧的进程间通信,以及两端各自进程内通信。
正常流程中较为关键的一点是,新的要显示的Activity在resume后,App侧的主线程空闲下来才会通知AMS执行后续流程,将关闭的Activity销毁。那要是新的Activity在resume后,主线程一直在循环处理MessageQueue中堆积的msg呢?很显然,要是这样的话,通知AMS执行后续流程自然被延迟了,因此,Activity的onStop和onDestroy生命周期回调自然也就被延迟了。
延时10s是为什么
作为一个健壮的操作系统,当然要有一定的容错机制,不能说因为App侧主线程一直忙,AMS侧就不去销毁/回收已经死亡的Activity。要不然新手开发者开发的App会因为内存泄漏等问题分分钟玩死系统。那么这个容错机制是怎么设计的呢?
前面我们说兵分两路,一路是追踪AMS向App发起的IPC,唤起下一个要显示的Activity,一路是追踪唤起下一个Activity后AMS本身要进行的状态设置相关工作。分析完了AMS侧向App侧发起IPC后的正常流程后,我们继续分析AMS本身还做了哪些工作:
//in ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
next.completeResumeLocked();
}
// in ActivityRecord.java
final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener {
void completeResumeLocked() {
...
// Schedule an idle timeout in case the app doesn't do it for us.
// 设置一个超时的空闲时间,以便在App没有通知我们其有空的情形下也能执行相关流程
mStackSupervisor.scheduleIdleTimeoutLocked(this);
...
}
}
// in StackSupervisor.java
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,
RecentTasks.Callbacks {
void scheduleIdleTimeoutLocked(ActivityRecord next) {
//真相就在这里,发送一个延时10s的消息,确保正常流程行不通的情况下也能销毁Activity
Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
}
private final class ActivityStackSupervisorHandler extends Handler {
void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
synchronized (mService) {
//在前面我们分析正常流程的时候,已经将该方法的执行流程分析完了,不再赘述
activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
processPausingActivities, null);
}
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case IDLE_TIMEOUT_MSG: {
//延时10s后,就当Activity侧已经空闲下来了,执行后续流程
activityIdleInternal((ActivityRecord) msg.obj,
true /* processPausingActivities */);
} break;
...
}
}
}
要想使得Activity的onStop和onDestroy尽快得到回调,我们就该在写代码的时候,及时关闭、清理、移除不必要的主线程消息,并且尽可能的保证每个消息处理时间不要太长。