本文基于 android-10.0.0_r41 版别解说

上一节提到调用 mRootActivityContainer.resumeFocusedStacksTopActivities onPause 前一个 Activity。

需求留意的一点是: resumeFocusedStacksTopActivities 从办法名看上去,好像是要 resume 方针 Activity,实际上,当时情形下,仅仅 pause 发动端 Activity,也便是 pause Launcher Activity

接下来咱们来看源码实现:

    // frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
    boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (!mStackSupervisor.readyToResume()) {
            return false;
        }
        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackOnDisplay()
                || getTopDisplayFocusedStack() == targetStack)) {
            // 关注点
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        // ......
        return result;
    }

经过一些状况的判断后,接着调用 resumeTopActivityUncheckedLocked 办法:

    // /frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
    // 留意当时办法地点的目标是 targetStack 便是待发动的方针 Activity 地点的 ActivityStack
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mInResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }
        boolean result = false;
        try {
            // Protect against recursion.
            mInResumeTopActivity = true;
            // 关注点
            result = resumeTopActivityInnerLocked(prev, options);
            // resume 进程中,假如锁屏了,sleep 当时 Activity
            // 当时是 onPause 进程,关系不大
            // When resuming the top activity, it may be necessary to pause the top activity (for
            // example, returning to the lock screen. We suppress the normal pause logic in
            // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
            // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
            // to ensure any necessary pause logic occurs. In the case where the Activity will be
            // shown regardless of the lock screen, the call to
            // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }
        return result;
    }

接着调用 resumeTopActivityInnerLocked 办法,需求留意的是:

  • 这个时分,内部的数据结构(ActivityRecord TaskRecord ActivityStack)都设置好了。
  • resumeTopActivityInnerLocked 是 ActivityStack 目标的成员函数,当时办法地点的目标是 targetStack ,便是待发动的方针 Activity 地点的 ActivityStack
  • 办法参数 pre 姓名有点迷惑,实际上 pre 对应的 Activity 是方针待发动 Activity
    // /frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
    /*
        ActivityRecord prev:方针 Activity 的相关信息
        ActivityOptions options:额外附加信息
    */
    @GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked (ActivityRecord prev, ActivityOptions options) {
        // 假如体系还未发动结束,那 AMS 还不能正常工作,所以也不能显现 Activity,主要是为防止没有开机发动完成
        if (!mService.isBooting() && !mService.isBooted()) {
            // Not ready yet!
            return false;
        }
        // 便是方针 Activity,和参数中的 pre 是同一个目标
        // 因为内部数据结构(ActivityRecord TaskRecord ActivityStack)都安排好了,所以 topRunningActivityLocked 获取到的便是方针 Activity
        // 可是实际上那个方针 Activity 还没有 Running
        ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        final boolean hasRunningActivity = next != null;
        // ......
        // 当时或许存在一些正处于 Intializing 状况的 ActivityRecord,
	    // 假如这些 ActivityRecord 不是位于栈顶,而且正在履行窗口发动动画,
	    // 那么,就需求撤销这些 Activity 的发动动画。
        mRootActivityContainer.cancelInitializingActivities();
        //这个变量是表明是否回调 Activity 中的 onUserLeaveHint 和 onUserInteraction 函数
        // Remember how we'll process this pause/resume situation, and ensure
        // that the state is reset however we wind up proceeding.
        boolean userLeaving = mStackSupervisor.mUserLeaving;
        mStackSupervisor.mUserLeaving = false;
        //......
        next.delayedResume = false;
        final ActivityDisplay display = getDisplay();
        // ......
        /*
			在 mStackSupervisor 中存在很多的数据结构,用来统一管理 ActivityRecord 的状况
            mStoppingActivities 记载了当时所有处于 Stopping 状况的 ActivityRecord
	    	mGoingToSleepActivities 记载了当时所有要进入休眠状况的 ActivityRecord
            在某些场景下,待显现的 ActivityRecord 或许处于这些数组中,需求从中剔除
		*/
        // The activity may be waiting for stop, but that is no longer
        // appropriate for it.
        mStackSupervisor.mStoppingActivities.remove(next);
        mStackSupervisor.mGoingToSleepActivities.remove(next);
        next.sleeping = false;
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
        // ......
        /*
			setLaunchSource 设置待发动的 Activity 的信息
			跟进 setLaunchSource 源码发现它最终会获取一个 WakeLock,保证在显现 Activity 的进程中,体系不会进行休眠状况
		*/
        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
        boolean lastResumedCanPip = false;
        ActivityRecord lastResumed = null;
        final ActivityStack lastFocusedStack = display.getLastFocusedStack();
        if (lastFocusedStack != null && lastFocusedStack != this) { // 进入
            // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
            // represent the last resumed activity. However, the last focus stack does if it isn't null.
            lastResumed = lastFocusedStack.mResumedActivity;
            if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
                // The user isn't leaving if this stack is the multi-window mode and the last
                // focused stack should still be visible.
                if(DEBUG_USER_LEAVING) Slog.i(TAG_USER_LEAVING, "Overriding userLeaving to false"
                        + " next=" + next + " lastResumed=" + lastResumed);
                userLeaving = false;
            }
            lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
                    "resumeTopActivity", userLeaving /* beforeStopping */);
        }
        // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity
        // to be paused, while at the same time resuming the new resume activity only if the
        // previous activity can't go into Pip since we want to give Pip activities a chance to
        // enter Pip before resuming the next activity.
        final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
                && !lastResumedCanPip; // false
        /* 
		  开端 Pause Activity
 		*/
        boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) { // 不进入
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        if (pausing && !resumeWhilePausing) {
            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
                    "resumeTopActivityLocked: Skip resume: need to start pausing");
            // At this point we want to put the upcoming activity's process
            // at the top of the LRU list, since we know we will be needing it
            // very soon and it would be a waste to let it get killed if it
            // happens to be sitting towards the end.
            if (next.attachedToProcess()) {
                next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                        true /* activityChange */, false /* updateOomAdj */);
            }
            if (lastResumed != null) { // 进入这个分支
                lastResumed.setWillCloseOrEnterPip(true);
            }
            // 回来
            return true;
        } 
        // ......
        return true;
    }

接着开端履行 pauseBackStacks 办法, pause 前一个 Activity。

    // services/core/java/com/android/server/wm/ActivityDisplay.java
    boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
        boolean someActivityPaused = false;
        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = mStacks.get(stackNdx);
            final ActivityRecord resumedActivity = stack.getResumedActivity();
            if (resumedActivity != null
                    && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE
                        || !stack.isFocusable())) {
                if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
                        " mResumedActivity=" + resumedActivity);
                someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
                        dontWait);
            }
        }
        return someActivityPaused;
    }

pauseBackStacks 的使命便是经过循环找到栈顶 Activity 是 resumed 状况且非 Focusable 的 ActivityStack,然后调用 ActivityStack 的 startPausingLocked 办法:

咱们假定的情形下,这儿的 ActivityStack 便是 Launcher App 地点的 ActivityStack

    // services/core/java/com/android/server/wm/ActivityStack.java
    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {
        if (mPausingActivity != null) { // mPausingActivity 为 null,不进入
            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                    + " state=" + mPausingActivity.getState());
            if (!shouldSleepActivities()) {
                // Avoid recursion among check for sleep and complete pause during sleeping.
                // Because activity will be paused immediately after resume, just let pause
                // be completed by the order of activity paused from clients.
                completePauseLocked(false, resuming);
            }
        }
        // mResumedActivity 便是 Launcher Activity
        ActivityRecord prev = mResumedActivity;
        if (prev == null) {
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mRootActivityContainer.resumeFocusedStacksTopActivities();
            }
            return false;
        }
        // resuming 是待发动的 Activity
        if (prev == resuming) { // 不进入
            Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
            return false;
        }
        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
        else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
        mPausingActivity = prev; // Laucher
        mLastPausedActivity = prev;
        // null
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
        // 设置状况,会建议 Binder RPC 调用到 app 通知状况改变,不是重点
        prev.setState(PAUSING, "startPausingLocked");
        // 记载一个时间值,表明方针 Activity 开端 active 了
        prev.getTaskRecord().touchActiveTime();
        clearLaunchTime(prev);
        mService.updateCpuStats();
        if (prev.attachedToProcess()) { // 进入分支
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
            try {
                EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                        prev.shortComponentName, "userLeaving=" + userLeaving);
                // 走这儿,建议 Binder RPC 调用,通知 App 履行 onPause
                mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                        prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                                prev.configChangeFlags, pauseImmediately));
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        }
        // ...... 
    }

接着调用 mService.getLifecycleManager().scheduleTransaction 向 App 端建议 Binder RPC 调用:

    // /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
    /**
     * Schedule a single lifecycle request or callback to client activity.
     * @param client Target client.
     * @param activityToken Target activity token.
     * @param stateRequest A request to move target activity to a desired lifecycle state.
     * @throws RemoteException
     *
     * @see ClientTransactionItem
     */
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }

接着调用重载 scheduleTransaction:

    // /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        // 关注点
        transaction.schedule();
        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();
        }
    }    

接着调用 schedule:


 // /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
    /** Target client. */
    private IApplicationThread mClient;
    /**
     * Schedule the transaction after it was initialized. It will be send to client and all its
     * individual parts will be applied in the following sequence:
     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
     *    that needs to be done before actually scheduling the transaction for callbacks and
     *    lifecycle state request.
     * 2. The transaction message is scheduled.
     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
     *    all callbacks and necessary lifecycle transitions.
     */
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

层层调用到 IApplicationThread 的 scheduleTransaction 办法,这是一个 Binder RPC 调用:

现在只长途调用 App 端的 scheduleTransaction 办法,pause 前一个 Activity,scheduleTransaction 办法是 oneway 的,所以很或许前一个 Activity 还没有 onPause, 该办法就回来了

它会长途调用到 Activity 端:

// /frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

这儿会发送一个 Message,ActivityThread 中的 Handler 中会处理到这个 Message:

// /frameworks/base/core/java/android/app/ActivityThread.java
        public void handleMessage(Message msg) {
                case EXECUTE_TRANSACTION:
                    // 从 Message 中取出音讯
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    // 履行音讯
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;            
        }
  • 从 Message 中取出音讯
  • 履行音讯

接着咱们来看履行音讯的进程:


    // /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
    public void execute(ClientTransaction transaction) {
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
        // ......
        // 履行回调
        executeCallbacks(transaction);
        // 履行生命周期
        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }

接着调用 executeLifecycleState 来履行生命周期:

    // /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
        /** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
        // 拿到 ActivityLifecycleItem,这儿是子类 PauseActivityItem
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        // ......
        // token 是一个索引值
        // 经过 token 能够拿到 ActivityClientRecord,这个目标是 App 端的,用于描绘描绘一个 Activity
        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
                    + lifecycleItem + " for activity: "
                    + getShortActivityName(token, mTransactionHandler));
        }
        if (r == null) {
            // Ignore requests for non-existent client records for now.
            return;
        }
        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
        // Execute the final transition with proper parameters.
        // 履行生命周期
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        // 履行生命周期后的操作也要关心
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

接着履行 PauseActivityItem 的 execute:

    // /frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        // 履行回调
        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
                "PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

client 的详细类型是 ActivityThread
接着履行到 ActivityThread 的 handlePauseActivity 办法:

// /frameworks/base/core/java/android/app/ActivityThread.java
    @Override
    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            if (userLeaving) { // userLeaving 相关的回调
                performUserLeavingActivity(r);
            }
            r.activity.mConfigChangeFlags |= configChanges;
            // 关注点
            performPauseActivity(r, finished, reason, pendingActions);
            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }
            mSomeActivitiesChanged = true;
        }
    }

接着调用 performPauseActivity:

    // /frameworks/base/core/java/android/app/ActivityThread.java
    /**
     * Pause the activity.
     * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
     */
    private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
            PendingTransactionActions pendingActions) {
        //......
        // 关注点
        performPauseActivityIfNeeded(r, reason);
        //......
    }

接着调用 performPauseActivityIfNeeded

    // /frameworks/base/core/java/android/app/ActivityThread.java
    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        // ......
        try {
            r.activity.mCalled = false;
            // 关注点
            mInstrumentation.callActivityOnPause(r.activity);
            if (!r.activity.mCalled) {
                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                        + " did not call through to super.onPause()");
            }
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException("Unable to pause activity "
                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
            }
        }
        r.setState(ON_PAUSE);
    }

接着会调用 Activity 的 callActivityOnPause:

    // /frameworks/base/core/java/android/app/Instrumentation.java
    /**
     * Perform calling of an activity's {@link Activity#onPause} method.  The
     * default implementation simply calls through to that method.
     * 
     * @param activity The activity being paused.
     */
    public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }

接着履行 Activity 的 performPause 办法:

// /frameworks/base/core/java/android/app/Activity.java
    final void performPause() {
        dispatchActivityPrePaused();
        mDoReportFullyDrawn = false;
        mFragments.dispatchPause();
        mCalled = false;
        onPause();
        writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
        mResumed = false;
        if (!mCalled && getApplicationInfo().targetSdkVersion
                >= android.os.Build.VERSION_CODES.GINGERBREAD) {
            throw new SuperNotCalledException(
                    "Activity " + mComponent.toShortString() +
                    " did not call through to super.onPause()");
        }
        dispatchActivityPostPaused();
    }

在这儿就会履行到 Activity 的 onPause 生命周期办法。

生命周期履行完后,接下来回到之前的 executeLifecycleState 办法中:

        /** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
        // 拿到 ActivityLifecycleItem,这儿是子类 PauseActivityItem
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        // ......
        // 履行生命周期
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

在调用 execute 办法,履行完 onPause 生命周期办法后,接着会调用到 lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);

    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        if (mDontReport) {
            return;
        }
        try {
            // TODO(lifecycler): Use interface callback instead of AMS.
            ActivityTaskManager.getService().activityPaused(token);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

在这儿,会长途调用到 atms 的 activityPaused 办法。这部分内容咱们就留在下一节在分析了。

参考资料