从源码分析按 Back 键后 Activity 的生命周期(页面 Activity 结束后的生命周期)

从源码分析按 Back 键后 Activity 的生命周期(页面 Activity 结束后的生命周期)

这篇文章的重点通过源码分析你在按了 Back 键后到底发生了什么? Activity 的生命周期为什么会是这样呢?

测试按 Back 键后 Activity 的生命周期

首先测试下按返回键后, Activity 的生命周期,其中 TestActivity 是二级页 Activity, MainActivity 是上一页的 Activity
生命周期是先 TestActivity onPause, 然后走 MainActivity 的流程,等 MainActivity 的流程走完,最后再走 TestActivity 的 onStop 和 onDestroy

TestActivity: onBackPressed
TestActivity: onPause
MainActivity: onRestart
MainActivity: onStart
MainActivity: onResume
TestActivity: onStop
TestActivity: onDestroy

从源码分析按 Back 键后 Activity 的生命周期

既然要分析 Back 键后的生命周期,当然要从按 Back 键开始

public class MainActivity extends AppCompatActivity

public void onBackPressed() {
    super.onBackPressed();
}
public class AppCompatActivity extends FragmentActivity
public class FragmentActivity extends ComponentActivity

通过继承关系也不奇怪, super.onBackPressed() 最终是由 ComponentActivity 实现的

androidx\activity\ComponentActivity.java

public void onBackPressed() {
    mOnBackPressedDispatcher.onBackPressed();
}

接下来就分发给了 OnBackPressedDispatcher 实现

androidx\activity\OnBackPressedDispatcher.java

public void onBackPressed() {
    Iterator<OnBackPressedCallback> iterator =
            mOnBackPressedCallbacks.descendingIterator();
    while (iterator.hasNext()) {
        OnBackPressedCallback callback = iterator.next();
        if (callback.isEnabled()) {
            callback.handleOnBackPressed();
            return;
        }
    }
    if (mFallbackOnBackPressed != null) {
        mFallbackOnBackPressed.run();
    }
}

可以忽略 mOnBackPressedCallbacks 部分(动态添加了,按 Back 键涉及不到,暂时忽略),看看 mFallbackOnBackPressed 执行的是什么

androidx\activity\OnBackPressedDispatcher.java

private final Runnable mFallbackOnBackPressed;

public OnBackPressedDispatcher(@Nullable Runnable fallbackOnBackPressed) {
    mFallbackOnBackPressed = fallbackOnBackPressed;
}

最终还是找回到了 ComponentActivity 这里,实现了 OnBackPressedDispatcher 的 run 方法

androidx\activity\ComponentActivity.java

private final OnBackPressedDispatcher mOnBackPressedDispatcher =
        new OnBackPressedDispatcher(new Runnable() {
            @Override
            public void run() {
                ComponentActivity.super.onBackPressed();
            }
        });

最终实现 onBackPressed 方法的还是在 Activity 里面,一步步往下找,可以找到最终调用了 ActivityManager.getService() 的 finishActivity 方法

android\app\Activity.java

public void onBackPressed() {
    if (mActionBar != null && mActionBar.collapseActionView()) {
        return;
    }

    FragmentManager fragmentManager = mFragments.getFragmentManager();

    if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
        finishAfterTransition();
    }
}

public void finishAfterTransition() {
    if (!mActivityTransitionState.startExitBackTransition(this)) {
        finish();
    }
}

public void finish() {
    finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}

private void finish(int finishTask) {
    if (mParent == null) {

        ...

        try {
            if (resultData != null) {
                resultData.prepareToLeaveProcess(this);
            }
            if (ActivityManager.getService()
                    .finishActivity(mToken, resultCode, resultData, finishTask)) {
                mFinished = true;
            }
        } catch (RemoteException e) {
            // Empty
        }
    } else {
        mParent.finishFromChild(this);
    }

    ...

}

ActivityManager.getService() 可以知道是由 ActivityManagerService 实现的

前面的流程知道 finishTask = FINISH_TASK_WITH_ROOT_ACTIVITY, 所以走 else 分支

com\android\server\am\ActivityManagerService.java

public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
        int finishTask) {
    
    ...

        try {
            boolean res;
            final boolean finishWithRootActivity =
                    finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
            if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
                    || (finishWithRootActivity && r == rootR)) {
                res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
                        finishWithRootActivity, "finish-activity");
            } else {
            // finishTask = FINISH_TASK_WITH_ROOT_ACTIVITY, 所以走 else 分支
                res = tr.getStack().requestFinishActivityLocked(token, resultCode,
                        resultData, "app-request", true);
            }
            return res;
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }
}

进入 ActivityStack, 一步步找最终的实现的地方

com\android\server\am\ActivityStack.java

final boolean requestFinishActivityLocked(IBinder token, int resultCode,
        Intent resultData, String reason, boolean oomAdj) {
    ActivityRecord r = isInStackLocked(token);
    if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
            "Finishing activity token=" + token + " r="
            + ", result=" + resultCode + ", data=" + resultData
            + ", reason=" + reason);
    if (r == null) {
        return false;
    }

    finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
    return true;
}

final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
        String reason, boolean oomAdj) {
    return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
}


final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
        String reason, boolean oomAdj, boolean pauseImmediately) {
    // r.finishing = false
    if (r.finishing) {
        Slog.w(TAG, "Duplicate finish request for " + r);
        return false;
    }

    mWindowManager.deferSurfaceLayout();
    try {
        r.makeFinishingLocked();
        
        ...

        if (mResumedActivity == r) {
            
            ...

            if (mPausingActivity == null) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
                if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
                        "finish() => pause with userLeaving=false");
                startPausingLocked(false, false, null, pauseImmediately);
            }

            if (endTask) {
                mService.getLockTaskController().clearLockedTask(task);
            }
        } else if (!r.isState(PAUSING)) {

            ...

    } finally {
        mWindowManager.continueSurfaceLayout();
    }
}

找到 PAUSE_IMMEDIATELY 的常量在 ActivityStackSupervisor 里面,所以 pauseImmediately = !PAUSE_IMMEDIATELY = false
不需要立马 pause

com\android\server\am\ActivityStackSupervisor.java

static final boolean PAUSE_IMMEDIATELY = true;

finishActivityLocked 里面的 r.makeFinishingLocked 就是把 finishing 置位 true, 所以后面 r.finishing 的值都为 true 了

com\android\server\am\ActivityRecord.java

void makeFinishingLocked() {
    if (finishing) {
        return;
    }
    finishing = true;
    if (stopped) {
        clearOptionsLocked();
    }

    if (service != null) {
        service.mTaskChangeNotificationController.notifyTaskStackChanged();
    }
}

接下来开始真正的停止 Activity 的生命周期 startPausingLocked

com\android\server\am\ActivityStack.java

 * @param pauseImmediately True if the caller does not want to wait for the activity callback to
 *                         complete pausing.
// 如果不想要等待 activity 的回调,就设为 true,然后完成 pasue 操作
// 这里前面的流程知道 pauseImmediately = false, 想要 等待 activity 的回调,然后再完成 pasue 操作的
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    ...

    ActivityRecord prev = mResumedActivity;

    ...

    mPausingActivity = prev;
    
    ...

    if (prev.app != null && prev.app.thread != null) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
        try {
            EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
                    prev.shortComponentName, "userLeaving=" + userLeaving);
            mService.updateUsageStats(prev, false);
            // 具体执行 Activity 的 onPasue 生命周期
            mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                    PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
        } catch (Exception e) { ... }
    } else { ... }

    ...

    if (mPausingActivity != null) {
        
        ...

        if (pauseImmediately) { ... } else {
            // 执行 Pause 如果超时的机制
            schedulePauseTimeout(prev);
            return true;
        }

    } else { ... }
}

最多等待 Pause 超时 500 ms, 后面就会强制执行 Pause 的后续操作,因为操作和正常完成 Pause 流程类似,就不单独介绍了,有兴趣可以自己看

com\android\server\am\ActivityStack.java

private void schedulePauseTimeout(ActivityRecord r) {
    final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
    msg.obj = r;
    r.pauseTime = SystemClock.uptimeMillis();
    mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
}

private static final int PAUSE_TIMEOUT = 500;

看下 PauseActivityItem 里面是怎么执行 onPause 操作的
看到最终执行完 PauseActivityItem 里面 execute 里面操作(这种执行 Activity onPause 生命周期的操作,因为和后面 onDestroy 的操作类似,但是比 onDestroy 流程简单,就单单列出 OnDestroy 的流程,onPause 流程就不多余说明,有兴趣可以自己了解,这里不具体展开了),结束后还是回到了 ActivityManager.getService() == ActivityManagerService 里面执行了 Pause 后续操作

android\app\servertransaction\PauseActivityItem.java

// Perform all actions that need to happen after execution, e.g. report the result to server.
// 所有的操作需要发生在执行之后
public void postExecute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    if (mDontReport) {
        return;
    }
    try {
        // TODO(lifecycler): Use interface callback instead of AMS.
        ActivityManager.getService().activityPaused(token);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
}

兜兜转转,其实还是需要 ActivityManagerService 具体执行

com\android\server\am\ActivityManagerService.java

public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

ActivityStack 继续执行 activityPaused 的后续操作

com\android\server\am\ActivityStack.java

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

    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                    + (timeout ? " (due to timeout)" : " (pause complete)"));
            mService.mWindowManager.deferSurfaceLayout();
            try {
                completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
            } finally {
                mService.mWindowManager.continueSurfaceLayout();
            }
            return;
        } else { ... }
    }
    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}

开始结束 Pause 的操作

  1. 首先结束这个 Activity (也就是 TestActivity ),其实这里没有真正执行 onStop 和 onDestroy 的生命周期,只是加入要结束的队列,等空闲的时候真正执行
  2. 开始上一个 Activity 的生命周期(也就是 MainActivity )

com\android\server\am\ActivityStack.java

private 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");
        // 前面已经把 finishing 设置为 true
        if (prev.finishing) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
            // 1. 首先结束这个 Activity (也就是 TestActivity ),其实这里没有真正执行 onStop 和 onDestroy 的生命周期,只是加入要结束的队列,等空闲的时候真正执行
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
                    "completedPausedLocked");
        } else if (prev.app != null) { ... } else { ... }

        if (prev != null) {
            prev.stopFreezingScreenLocked(true /*force*/);
        }
        mPausingActivity = null;
    }

    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!topStack.shouldSleepOrShutDownActivities()) {
            // 2. 开始上一个 Activity 的生命周期(也就是 MainActivity )
            mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
        } else {
            checkReadyForSleep();
            ActivityRecord top = topStack.topRunningActivityLocked();
            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.
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
        }
    }

    ...

}

先看下第一个步骤如何结束这个 Activity (也就是 TestActivity )

前面调用方法的 mode = FINISH_AFTER_VISIBLE, 直接走 if 分支,最终调用了 addToStopping 方法

addToStopping 方法,其实只是把当前的 activity 加到了 mStoppingActivities 而已,没有立马走 activity 的生命周期

com\android\server\am\ActivityStack.java

final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,
        String reason) {
    
    final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(
            true /* considerKeyguardState */);

    // mode = FINISH_AFTER_VISIBLE, 直接走 if 分支
    if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
            && next != null && !next.nowVisible) {
        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
            addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */);
        }
        if (DEBUG_STATES) Slog.v(TAG_STATES,
                "Moving to STOPPING: "+ r + " (finish requested)");
        r.setState(STOPPING, "finishCurrentActivityLocked");
        if (oomAdj) {
            mService.updateOomAdjLocked();
        }
        return r;
    }

    ...

}

void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
    if (!mStackSupervisor.mStoppingActivities.contains(r)) {
        mStackSupervisor.mStoppingActivities.add(r);
    }

    // If we already have a few activities waiting to stop, then give up
    // on things going idle and start clearing them out. Or if r is the
    // last of activity of the last task the stack will be empty and must
    // be cleared immediately.
    boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
            || (r.frontOfTask && mTaskHistory.size() <= 1);
    if (scheduleIdle || forceIdle) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
                + forceIdle + "immediate=" + !idleDelayed);
        if (!idleDelayed) {
            mStackSupervisor.scheduleIdleLocked();
        } else {
            mStackSupervisor.scheduleIdleTimeoutLocked(r);
        }
    } else {
        checkReadyForSleep();
    }
}

然后看前面第二步走的开始上一个 Activity 的生命周期(也就是 MainActivity )

com\android\server\am\ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!readyToResume()) {
        return false;
    }

    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || !r.isState(RESUMED)) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.isState(RESUMED)) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }

    return false;
}

resumeTopActivityInnerLocked 这就走 Activity 的重新 resume 的生命周期,就不细讲了,有兴趣可以自己看。

com\android\server\am\ActivityStack.java

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);

        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next == null || !next.canTurnScreenOn()) {
            checkReadyForSleep();
        }
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }

    return result;
}

讲完了 TestActivity onPause 和 MainActivity onStart, onResume 的生命周期

再来看下 TestActivity 是在什么时候 onStop, onDestroy 的,就明白整个生命周期流程为什么是这样的了

通过 mStoppingActivities 一步步往回找,最终在 ActivityThread 的 Idler 的空闲 Handler 里面找到了移除 mStoppingActivities 里面的 activity 的源头,而 Idler 是在 handleResumeActivity 的时候加入 Looper 的

看到这里就明白了,TestActivity onPause 之后为什么是 MainActivity 的 onStart 了

都知道 IdleHandler 在 Handler 里面没有消息了,空闲了才会执行的,看下 Idler 怎么涉及到移除 mStoppingActivities 里面的 activity 吧

android\app\ActivityThread.java

public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
        String reason) {
    ...
    Looper.myQueue().addIdleHandler(new Idler());
}

private class Idler implements MessageQueue.IdleHandler {
    @Override
    public final boolean queueIdle() {
        ActivityClientRecord a = mNewActivities;
        boolean stopProfiling = false;
        if (mBoundApplication != null && mProfiler.profileFd != null
                && mProfiler.autoStopProfiler) {
            stopProfiling = true;
        }
        if (a != null) {
            mNewActivities = null;
            IActivityManager am = ActivityManager.getService();
            ActivityClientRecord prev;
            do {
                if (localLOGV) Slog.v(
                    TAG, "Reporting idle of " + a +
                    " finished=" +
                    (a.activity != null && a.activity.mFinished));
                if (a.activity != null && !a.activity.mFinished) {
                    try {
                        am.activityIdle(a.token, a.createdConfig, stopProfiling);
                        a.createdConfig = null;
                    } catch (RemoteException ex) {
                        throw ex.rethrowFromSystemServer();
                    }
                }
                prev = a;
                a = a.nextIdle;
                prev.nextIdle = null;
            } while (a != null);
        }
        if (stopProfiling) {
            mProfiler.stopProfiling();
        }
        ensureJitEnabled();
        return false;
    }
}

最后还是找到了 ActivityManagerService 里面的 activityIdle 方法

com\android\server\am\ActivityManagerService.java

public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
    final long origId = Binder.clearCallingIdentity();
    synchronized (this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            ActivityRecord r =
                    mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
                            false /* processPausingActivities */, config);
            if (stopProfiling) {
                if ((mProfileProc == r.app) && mProfilerInfo != null) {
                    clearProfilerLocked();
                }
            }
        }
    }
    Binder.restoreCallingIdentity(origId);
}

再回到 ActivityStackSupervisor 当中

  1. 调用 processStoppingActivitiesLocked 方法来获取需要移除的 activity(其实就是拿到 mStoppingActivities 里面的 activity)
  2. 执行 activity 的生命周期

com\android\server\am\ActivityStackSupervisor.java

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
        boolean processPausingActivities, Configuration config) {
    
    ...

    // Atomically retrieve all of the other things to do.
    final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
            true /* remove */, processPausingActivities);
    
    ...

    // Stop any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NS; i++) {
        r = stops.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) {
            if (r.finishing) {
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
                        "activityIdleInternalLocked");
            } else {
                stack.stopActivityLocked(r);
            }
        }
    }

    ...

}

先看第一个步骤,具体看下 processStoppingActivitiesLocked 怎么拿的

com\android\server\am\ActivityStackSupervisor.java

final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity,
        boolean remove, boolean processPausingActivities) {
    ArrayList<ActivityRecord> stops = null;

    final boolean nowVisible = allResumedActivitiesVisible();
    for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
        ActivityRecord s = mStoppingActivities.get(activityNdx);
        
        ...

                if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
                if (stops == null) {
                    stops = new ArrayList<>();
                }
                stops.add(s);
                mStoppingActivities.remove(activityNdx);
        }
    }

    return stops;
}

再看下第二个步骤,怎么执行 activity 的生命周期,结束掉 activity 的

这里的 mode == FINISH_IMMEDIATELY,所以走的下面的流程

com\android\server\am\ActivityStack.java

final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,
        String reason) {
    
    ...

    r.setState(FINISHING, "finishCurrentActivityLocked");
    final boolean finishingActivityInNonFocusedStack
            = r.getStack() != mStackSupervisor.getFocusedStack()
            && prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;

    // mode == FINISH_IMMEDIATELY, 所以走这里的流程
    if (mode == FINISH_IMMEDIATELY
            || (prevState == PAUSED
                && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
            || finishingActivityInNonFocusedStack
            || prevState == STOPPING
            || prevState == STOPPED
            || prevState == ActivityState.INITIALIZING) {
        r.makeFinishingLocked();
        boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);

        ...
    }
    ...
}

来看看是怎么结束 activity 的

通过 ClientLifecycleManager 执行 DestroyActivityItem 的方法

其实看到 mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken, DestroyActivityItem.obtain(r.finishing, r.configChangeFlags)); 这一步,就知道 Activity 要执行 onDestroy 的生命周期,但是这里还有一点疑惑,Activity 的 onStop 生命周期都没走,怎么就走了 onDestroy 了呢?

com\android\server\am\ActivityStack.java

final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {

        ...

        try {
            if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
            mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
                    DestroyActivityItem.obtain(r.finishing, r.configChangeFlags));
        } catch (Exception e) {
            // We can just ignore exceptions here...  if the process
            // has crashed, our death notification will clean things
            // up.
            //Slog.w(TAG, "Exception thrown during finish", e);
            if (r.finishing) {
                removeActivityFromHistoryLocked(r, reason + " exceptionInScheduleDestroy");
                removedFromHistory = true;
                skipDestroy = true;
            }
        }

        ...
}

看看 ClientLifecycleManager 怎么具体执行的

com\android\server\am\ClientLifecycleManager.java

void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
        @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
    final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
            stateRequest);
    scheduleTransaction(clientTransaction);
}

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();
    }
}

最终还是 ActivityThread 的 ApplicationThread 执行的

android\app\servertransaction\ClientTransaction.java

private IApplicationThread mClient;

public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

还是回到了 ActivityThread 里面执行

android\app\ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }
}    

看继承关系,走的是 ClientTransactionHandler 里面的 scheduleTransaction 方法

android\app\ClientTransactionHandler.java
public final class ActivityThread extends ClientTransactionHandler

void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

sendMessage 最终还是发送给了 ActivityThread 里面的名为 H 的 Handler

android\app\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);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

final H mH = new H();

class H extends Handler {
    public void handleMessage(Message msg) {
        case EXECUTE_TRANSACTION:
            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;
    }
}

一步步走下来,知道要具体执行的地方

execute --> executeLifecycleState --> cycleToPath

android\app\servertransaction\TransactionExecutor.java

public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}


private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    if (lifecycleItem == null) {
        // No lifecycle request, return early.
        return;
    }
    log("Resolving lifecycle state: " + lifecycleItem);

    final IBinder token = transaction.getActivityToken();
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    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 */);

    // Execute the final transition with proper parameters.
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}


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);
}

先看下一个调试的截图,可以看到 start = 4, finish = 6

看 ActivityLifecycleItem 里面定义可以知道,start = ON_PAUSE, finish = ON_DESTROY

在这里插入图片描述

android\app\servertransaction\ActivityLifecycleItem.java

public abstract class ActivityLifecycleItem extends ClientTransactionItem {
    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;
    public static final int ON_RESTART = 7;
}

如果不理解为什么会这样,看下 DestroyActivityItem 里面获取到的 getTargetState = ON_DESTROY, 而 TestActivity 走了 onPause 生命周期,还没走 onStop 生命周期,所以 start = ON_PAUSE

android\app\servertransaction\DestroyActivityItem.java

public class DestroyActivityItem extends ActivityLifecycleItem {
    @Override
    public int getTargetState() {
        return ON_DESTROY;
    }
}

getLifecyclePath 是获取生命周期的轨迹,其实就是要走完整的生命周期流程,所以这样设置,不会从 onPause 跳到 onDestroy,必须经过 onStop

android\app\servertransaction\TransactionExecutorHelper.java

public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
    if (start == UNDEFINED || finish == UNDEFINED) {
        throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
    }
    if (start == ON_RESTART || finish == ON_RESTART) {
        throw new IllegalArgumentException(
                "Can't start or finish in intermittent RESTART state");
    }
    if (finish == PRE_ON_CREATE && start != finish) {
        throw new IllegalArgumentException("Can only start in pre-onCreate state");
    }

    mLifecycleSequence.clear();
    if (finish >= start) {
        // just go there
        for (int i = start + 1; i <= finish; i++) {
            mLifecycleSequence.add(i);
        }
    } else { // finish < start, can't just cycle down
        if (start == ON_PAUSE && finish == ON_RESUME) {
            // Special case when we can just directly go to resumed state.
            mLifecycleSequence.add(ON_RESUME);
        } else if (start <= ON_STOP && finish >= ON_START) {
            // Restart and go to required state.

            // Go to stopped state first.
            for (int i = start + 1; i <= ON_STOP; i++) {
                mLifecycleSequence.add(i);
            }
            // Restart
            mLifecycleSequence.add(ON_RESTART);
            // Go to required state
            for (int i = ON_START; i <= finish; i++) {
                mLifecycleSequence.add(i);
            }
        } else {
            // Relaunch and go to required state

            // Go to destroyed state first.
            for (int i = start + 1; i <= ON_DESTROY; i++) {
                mLifecycleSequence.add(i);
            }
            // Go to required state
            for (int i = ON_CREATE; i <= finish; i++) {
                mLifecycleSequence.add(i);
            }
        }
    }

    // Remove last transition in case we want to perform it with some specific params.
    if (excludeLastState && mLifecycleSequence.size() != 0) {
        mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
    }

    return mLifecycleSequence;
}

通过 for 循环,从头执行到位一个个按顺序执行,也就是先 onStop 后 onDestroy

android\app\servertransaction\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);
        switch (state) {
            ...
            case ON_STOP:
                mTransactionHandler.handleStopActivity(r.token, false /* show */,
                        0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                        "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;
                ...
        }
    }
}

下面就很简单了,就是怎么一步步执行到 Activity 的 onStop 方法的,也就不一一介绍了

android\app\ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler

public void handleStopActivity(IBinder token, boolean show, int configChanges,
        PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
    final ActivityClientRecord r = mActivities.get(token);
    r.activity.mConfigChangeFlags |= configChanges;

    final StopInfo stopInfo = new StopInfo();
    performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
            reason);

    ...
}


private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
        boolean saveState, boolean finalStateRequest, String reason) {
    if (r != null) {
        ...

        if (!keepShown) {
            callActivityOnStop(r, saveState, reason);
        }
    }
}

private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
    
    ...

    try {
        r.activity.performStop(false /*preserveWindow*/, reason);
    } catch (SuperNotCalledException e) { ... } 

    ...
}

android\app\Activity.java

final void performStop(boolean preserveWindow, String reason) {
    mDoReportFullyDrawn = false;
    mFragments.doLoaderStop(mChangingConfigurations /*retain*/);

    // Disallow entering picture-in-picture after the activity has been stopped
    mCanEnterPictureInPicture = false;

    if (!mStopped) {
        ....
        mInstrumentation.callActivityOnStop(this);
        ...
    }
    mResumed = false;
}

android\app\Instrumentation.java

public void callActivityOnStop(Activity activity) {
    activity.onStop();
}

android\app\Activity.java

protected void onStop() {
    ...
}

总结

为什么 TestActivity onPause 后执行了 MainActivity onStart, onResume 的生命周期呢?

其实因为 TestActivity onPause 执行后,只是把要暂停的 TestActivity 加入了 mStoppingActivities 里面,等待 Handler 空闲的时候,而且必须是在 MainActivity onResume 之后的空闲才行,再执行 TestActivity 的 onStop 和 onDestroy。

TestActivity onPause 后立马执行了 MainActivity onStart, onResume, 所以 Handler 没有空闲,当然不会立马执行 TestActivity 的 onStop 和 onDestroy 了。

其实这也是可以理解, TestActivity onPause 后,APP 马上就没有画面了,需要下一个 MainActivity 先执行,保持 APP 有画面,相当于优先级高, TestActivity 可以在背后空闲的时候再处理结束

猜你喜欢

转载自blog.csdn.net/qq_16927853/article/details/109069245
今日推荐