当前Activity的onPause执行完后,调用Paused接口
阅读原文时间:2021年04月22日阅读:1

目录

前言

在前文中已经讲到.

  1. Launcher拉起新的Activity,并在ATMS中执行pause Activity的操作,以及当前Activity执行Pause的流程.
  2. 在当前Activity执行pause时同步执行拉起新进程操作.

本文主要讲当前Activity已经执行完Pause操作,调用ATMS的activityPaused接口,告知当前Activity已经暂停成功了的流程.

详细流程分析

PauseActivityItem执行postExecute时,就会调用ActivityTaskManager.getService().activityPaused(token);这个方法通过binder调用到ATMS的activityPaused.

    public final void activityPaused(IBinder token) {
        synchronized (mGlobalLock) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
            if (r != null) {
                r.activityPaused(false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

这里首先通过token去获取了当前Pause的Activity在ATMS中对应的ActivityRecord实例,然后调用

ActivityRecord的activityPaused.

todo:Activity,ActivityRecord,token,stack,task之间的关系.

void activityPaused(boolean timeout) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                "Activity paused: token=" + appToken + ", timeout=" + timeout);

        final ActivityStack stack = getStack();

首先查找当前的ActivityRecord对应的ActivityStack

        if (stack != null) {
            removePauseTimeout();

            if (stack.mPausingActivity == this) {
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + this
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                mAtmService.deferWindowLayout();
                try {
                    stack.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
                } finally {
                    mAtmService.continueWindowLayout();
                }
                return;

如果stack正在pausing的Activity是当前Activity,那么调用stack.completePauseLocked去resume下一个待resume的activity.

            } else {
                if (isState(PAUSING)) {
                    setState(PAUSED, "activityPausedLocked");
                    if (finishing) {
                        if (DEBUG_PAUSE) Slog.v(TAG,
                                "Executing finish of failed to pause activity: " + this);
                        completeFinishing("activityPausedLocked");
                    }
                }
            }

如果当前在pausing的activity不是当前的这个Activity.那么做一些状态的处理.(假设Activity a pause但是超时了,那么在超时的时候就会调用paused操作.此时又把当前resume的Activity pause,而 a Activity有回调了activityPaused接口就会进入这个分支.)

        }

        mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
    }

如果当前Activity的堆栈为空,或者当前pausing Activity不是当前这个Activity,那么还要调用mRootWindowContainerensureActivitiesVisible.

这里pausing Activity就是当前这个Activity,所以执行stack.completePauseLocked

void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);

        if (prev != null) {
            prev.setWillCloseOrEnterPip(false);
            final boolean wasStopping = prev.isState(STOPPING);
            prev.setState(PAUSED, "completePausedLocked");
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                prev = prev.completeFinishing("completePausedLocked");
            } else if (prev.hasProcess()) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
                        + " wasStopping=" + wasStopping
                        + " visibleRequested=" + prev.mVisibleRequested);
                if (prev.deferRelaunchUntilPaused) {
                    // Complete the deferred relaunch that was waiting for pause to complete.
                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
                    prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
                } else if (wasStopping) {
                    // We are also stopping, the stop request must have gone soon after the pause.
                    // We can't clobber it, because the stop confirmation will not be handled.
                    // We don't need to schedule another stop, we only need to let it happen.
                    prev.setState(STOPPING, "completePausedLocked");
                } else if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) {
                    // Clear out any deferred client hide we might currently have.
                    prev.setDeferHidingClient(false);
                    // If we were visible then resumeTopActivities will release resources before
                    // stopping.
                    prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
                            "completePauseLocked");
                }
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
                prev = null;
            }
            // It is possible the activity was freezing the screen before it was paused.
            // In that case go ahead and remove the freeze this activity has on the screen
            // since it is no longer visible.
            if (prev != null) {
                prev.stopFreezingScreenLocked(true /*force*/);
            }
            mPausingActivity = null;
        }

先获取当前Activity栈中待pause的Activity,执行一些Activity pause后的收尾工作.

        if (resumeNext) {
            final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
            if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) {
                mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
            } else {
                checkReadyForSleep();
                final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null;
                if (top == null || (prev != null && top != prev)) {
                    // If there are no more activities available to run, do resume anyway to start
                    // something. Also if the top activity on the stack is not the just paused
                    // activity, we need to go ahead and resume it to ensure we complete an
                    // in-flight app switch.
                    mRootWindowContainer.resumeFocusedStacksTopActivities();
                }
            }
        }

如果需要resume 下一个activity,那么调用mRootWindowContainer.resumeFocusedStacksTopActivities去resume它.

上面两个不同参数的resumeFocusedStacksTopActivities方法的区别在于第一种是确定要拉起哪个堆栈中的Activity,另一个是要从所有的显示区域去找一个需要显示的堆栈,如果找不到的话则拉起Launcher.

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章