Activity onStop调用者是谁,为什么会延时调用?

非原创,整理

在这里插入图片描述

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尽快得到回调,我们就该在写代码的时候,及时关闭、清理、移除不必要的主线程消息,并且尽可能的保证每个消息处理时间不要太长。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值