Activity 的 finish 过程

1. 前言

本文以 Android 9.0 源码为基础,分析 Activity 的 finish 过程。要进行分析,必须先确定好场景,不然就没有了方向。我们分析的场景是这样的:
MainActivity 通过 startActivityForResult 方法启动了 SecondActivity,然后 SecondActivity 调用 finish() 方法关闭自己。

2. 正文

2.1 Activity.finish() 方法

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

DONT_FINISH_TASK_WITH_ACTIVITY 这个标记的含义是 Task isn’t finished when activity is finished,即当 Activity finish 掉时 Task 不会被 finish。

2.2 Activity.finish(int finishTask) 方法

  • int finishTask, DONT_FINISH_TASK_WITH_ACTIVITY
    /**
     * Finishes the current activity and specifies whether to remove the task associated with this
     * activity.
     */
    private void finish(int finishTask) {
    	// mParent 是 null
        if (mParent == null) {
            int resultCode;
            Intent resultData;
            synchronized (this) {
            	// 把 setResult() 方法中设置的 mResultCode,mResultData,
            	// 赋值给 resultCode,resultData。
                resultCode = mResultCode;
                resultData = mResultData;
            }
            if (false) Log.v(TAG, "Finishing self: token=" + mToken);
            try {
                if (resultData != null) {
                	// 准备 resultData 这个 Intent 离开应用进程
                    resultData.prepareToLeaveProcess(this);
                }
                if (ActivityManager.getService()
                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
                    // 标记 mFinished 值为 true。
                    mFinished = true;
                }
            } catch (RemoteException e) {
                // Empty
            }
        } else {
            mParent.finishFromChild(this);
        }

        // Activity was launched when user tapped a link in the Autofill Save UI - Save UI must
        // be restored now.
        if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
            getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_RESTORE,
                    mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
        }
    }

2.3 ActivityManagerService.finishActivity() 方法

  • IBinder token, mToken,是在 Activity 中的 attach() 方法中被赋值的,它指向了我们想要 finish 的 Activity
  • int resultCode, 这里按照为 Activity.RESULT_OK 来分析
  • Intent resultData, 一个不为 null 的 Intent 对象
  • int finishTask, DONT_FINISH_TASK_WITH_ACTIVITY
  • 返回值 boolean,Activity 成功被关闭返回 true,仍在运行则返回 false
   /**
     * This is the internal entry point for handling Activity.finish().
     *
     * @param token The Binder token referencing the Activity we want to finish.
     * @param resultCode Result code, if any, from this Activity.
     * @param resultData Result data (Intent), if any, from this Activity.
     * @param finishTask Whether to finish the task associated with this Activity.
     *
     * @return Returns true if the activity successfully finished, or false if it is still running.
     */
    @Override
    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
            int finishTask) {
        // Refuse possible leaked file descriptors
        if (resultData != null && resultData.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        synchronized(this) {
        	// 根据 token 去获取对应的 ActivityRecord 对象,ActivityRecord 封装了 Activity 的信息。
            ActivityRecord r = ActivityRecord.isInStackLocked(token);
            if (r == null) {
            	// 如果 r 为 null,就返回 true,表示这个 Activity 已经 finish 掉了。
                return true;
            }
            // Keep track of the root activity of the task before we finish it
            // 获取 ActivityRecord 对象所属的 TaskRecord,TaskRecord 封装了 Task 的信息。
            TaskRecord tr = r.getTask();
            // Returns the first non-finishing activity from the root.
            // 从 Task 底部开始,返回第一个没有正在 finish 的 Activity。
            ActivityRecord rootR = tr.getRootActivity();
            if (rootR == null) {
                Slog.w(TAG, "Finishing task with all activities already finished");
            }
            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
            // finish.
            if (mLockTaskController.activityBlockedFromFinish(r)) {
                return false;
            }
			// mController 是 null,
			// 延伸一下:mController 是 IActivityController 对象,它的真正实现是在
			// ActivityManagerShellCommand.java 中的内部类:
			// static final class MyActivityController extends IActivityController.Stub {}
			// 而设置 mController 是通过 WatchDog 类的 
			// public void setActivityController(IActivityController controller) 方法
			// AMS 的 public void setActivityController(IActivityController controller, boolean imAMonkey) 方法。
            if (mController != null) {
                // Find the first activity that is not finishing.
                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
                if (next != null) {
                    // ask watcher if this is allowed
                    boolean resumeOK = true;
                    try {
                        resumeOK = mController.activityResuming(next.packageName);
                    } catch (RemoteException e) {
                        mController = null;
                        Watchdog.getInstance().setActivityController(null);
                    }

                    if (!resumeOK) {
                        Slog.i(TAG, "Not finishing activity because controller resumed");
                        return false;
                    }
                }
            }
            final long origId = Binder.clearCallingIdentity();
            try {
                boolean res;
                final boolean finishWithRootActivity =
                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; // false
                // 不会进入下面的分支
                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY // false
                        || (finishWithRootActivity && r == rootR)) {
                    // If requested, remove the task that is associated to this activity only if it
                    // was the root activity in the task. The result code and data is ignored
                    // because we don't support returning them across task boundaries. Also, to
                    // keep backwards compatibility we remove the task from recents when finishing
                    // task with root activity.
                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
                            finishWithRootActivity, "finish-activity");
                    if (!res) {
                        Slog.i(TAG, "Removing task failed to finish activity");
                    }
                } else { // 进入下面这个分支
                	// tr 是一个 TaskRecord 对象,tr.getStack() 获取的是一个 ActivityStack 对象。
                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
                            resultData, "app-request", true);
                    if (!res) {
                        Slog.i(TAG, "Failed to finish by app-request");
                    }
                }
                return res;
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }
    }

2.4 ActivityStack.requestFinishActivityLocked() 方法

  • IBinder token, mToken,是在 Activity 中的 attach() 方法中被赋值的,它指向了我们想要 finish 的 Activity
  • int resultCode, 这里按照为 Activity.RESULT_OK 来分析
  • Intent resultData, 一个不为 null 的 Intent 对象
  • String reason, “app-request”
  • boolean oomAdj, true
  • 返回值 boolean,activity 被 finish 掉则返回 true,否则返回 false
    /**
     * @return Returns true if the activity is being finished, false if for
     * some reason it is being left as-is.
     */
    final boolean requestFinishActivityLocked(IBinder token, int resultCode,
            Intent resultData, String reason, boolean oomAdj) {
        // 根据 token 在 ActivityStack 里面找出 ActivityRecord 对象。
        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) {
        	// 没找到,不能成功关闭 activity
            return false;
        }

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

2.5 ActivityStack.finishActivityLocked() 方法

  • ActivityRecord r, 对应于要关闭的 activity 的 信息封装对象
  • int resultCode, 这里按照为 Activity.RESULT_OK 来分析
  • Intent resultData, 一个不为 null 的 Intent 对象
  • String reason, “app-request”
  • boolean oomAdj, true
    /**
     * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
     */
    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
            String reason, boolean oomAdj) {
            // import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; 值为 true
        return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
    }

2.6 ActivityStack.finishActivityLocked() 方法

  • ActivityRecord r, 对应于要关闭的 activity 的 信息封装对象
  • int resultCode, 这里按照为 Activity.RESULT_OK 来分析
  • Intent resultData, 一个不为 null 的 Intent 对象
  • String reason, “app-request”
  • boolean oomAdj, true
  • boolean pauseImmediately, false
  • 返回值 boolean,如果 activity 已经从 activity 列表移除了,就返回 true;否则返回 false。
   /**
     * @return Returns true if this activity has been removed from the history
     * list, or false if it is still in the list and will be removed later.
     */
    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
            String reason, boolean oomAdj, boolean pauseImmediately) {
        if (r.finishing) {
        	// 要关闭的 Activity 正在 finish,返回 false
            Slog.w(TAG, "Duplicate finish request for " + r);
            return false;
        }
		// 开始推迟布局阶段
        mWindowManager.deferSurfaceLayout();
        try {
            r.makeFinishingLocked(); // 标记 r.finishing 为 true。
            // 获取 ActivityRecord 所属的 TaskRecord 对象
            final TaskRecord task = r.getTask();
            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
                    r.userId, System.identityHashCode(r),
                    task.taskId, r.shortComponentName, reason);
            // 获取 TaskRecord 里持有的 ActivityRecord 集合
            final ArrayList<ActivityRecord> activities = task.mActivities;
            // 找出当前的 ActivityRecord 在集合中的索引
            final int index = activities.indexOf(r);
            if (index < (activities.size() - 1)) { // 不是最顶层的条目
            	// ActivityRecord有一个属性是frontOfTask,表示ActivityRecord是否为TaskRecord的根Activity。
            	// 该函数设置TaskRecord中所有ActivityRecord的frontOfTask属性(is this the root activity of its task?),
            	// 从栈底往上开始遍历,
            	// 第一个不处于finishing状态的ActivityRecord的frontOfTask属性置成true,其他都为false
                task.setFrontOfTask();
                if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
                    // If the caller asked that this activity (and all above it)
                    // be cleared when the task is reset, don't lose that information,
                    // but propagate it up to the next activity.
                    ActivityRecord next = activities.get(index+1);
                    next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                }
            }
			// 暂停键盘事件的分发
            r.pauseKeyDispatchingLocked();
			// 调整处于焦点的 ActivityStack
            adjustFocusedActivityStack(r, "finishActivity");

            finishActivityResultsLocked(r, resultCode, resultData);

            final boolean endTask = index <= 0 && !task.isClearingToReuseTask(); // false
            final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE; // TRANSIT_ACTIVITY_CLOSE
            if (mResumedActivity == r) { // mResumedActivity 是 SecondActivity,r 也是 SecondActivity,进入此分支
                if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                        "Prepare close transition: finishing " + r);
                if (endTask) {
                    mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(
                            task.taskId);
                }
                mWindowManager.prepareAppTransition(transit, false);

                // Tell window manager to prepare for this one to be removed.
                r.setVisibility(false);

                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) { // false
                    mService.getLockTaskController().clearLockedTask(task);
                }
            } else if (!r.isState(PAUSING)) {
                // If the activity is PAUSING, we will complete the finish once
                // it is done pausing; else we can just directly finish it here.
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
                if (r.visible) {
                    prepareActivityHideTransitionAnimation(r, transit);
                }

                final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE
                        : FINISH_AFTER_PAUSE;
                final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj,
                        "finishActivityLocked") == null;

                // The following code is an optimization. When the last non-task overlay activity
                // is removed from the task, we remove the entire task from the stack. However,
                // since that is done after the scheduled destroy callback from the activity, that
                // call to change the visibility of the task overlay activities would be out of
                // sync with the activitiy visibility being set for this finishing activity above.
                // In this case, we can set the visibility of all the task overlay activities when
                // we detect the last one is finishing to keep them in sync.
                if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
                    for (ActivityRecord taskOverlay : task.mActivities) {
                        if (!taskOverlay.mTaskOverlay) {
                            continue;
                        }
                        prepareActivityHideTransitionAnimation(taskOverlay, transit);
                    }
                }
                return removedActivity;
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
            }

            return false;
        } finally {
        	// 继续布局阶段
            mWindowManager.continueSurfaceLayout();
        }
    }

2.6.1 ActivityStack.finishActivityResultsLocked() 方法

  • ActivityRecord r, 对应于要关闭的 activity 的 信息封装对象
  • int resultCode, 这里按照为 Activity.RESULT_OK 来分析
  • Intent resultData, 一个不为 null 的 Intent 对象
    private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
        // send the result
        ActivityRecord resultTo = r.resultTo; // MainActivity
        if (resultTo != null) { // resultTo 不是 null
            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
                    + " who=" + r.resultWho + " req=" + r.requestCode
                    + " res=" + resultCode + " data=" + resultData);
            if (resultTo.userId != r.userId) {
                if (resultData != null) {
                    resultData.prepareToLeaveUser(r.userId);
                }
            }
            if (r.info.applicationInfo.uid > 0) {
                mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
                        resultTo.packageName, resultData,
                        resultTo.getUriPermissionsLocked(), resultTo.userId);
            }
            // 把 result 相关信息,放入将来要接收这些信息的 Activity 的 ActivityRecord 对象中。
            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
                                     resultData);
            r.resultTo = null;
        }
        else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);

        // Make sure this HistoryRecord is not holding on to other resources,
        // because clients have remote IPC references to this object so we
        // can't assume that will go away and want to avoid circular IPC refs.
        r.results = null;
        r.pendingResults = null;
        r.newIntents = null;
        r.icicle = null;
    }

这里需要再看一下 ActivityRecord.addResultLocked() 方法:

	ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
    void addResultLocked(ActivityRecord from, String resultWho,
            int requestCode, int resultCode,
            Intent resultData) {
        // 把信息封装成 ActivityResult 对象,保存在集合中。
        ActivityResult r = new ActivityResult(from, resultWho,
                requestCode, resultCode, resultData);
        if (results == null) {
            results = new ArrayList<ResultInfo>();
        }
        results.add(r);
    }

2.7 ActivityStack.startPausingLocked() 方法

  • boolean userLeaving, false
  • boolean uiSleeping, false
  • ActivityRecord resuming, null
  • boolean pauseImmediately, false
  • 返回值 boolean, 如果一个 activity 当前处于 PAUSING 状态,则返回 true。
    /**
     * Start pausing the currently resumed activity.  It is an error to call this if there
     * is already an activity being paused or there is no resumed activity.
     *
     * @param userLeaving True if this should result in an onUserLeaving to the current activity.
     * @param uiSleeping True if this is happening with the user interface going to sleep (the
     * screen turning off).
     * @param resuming The activity we are currently trying to resume or null if this is not being
     *                 called as part of resuming the top activity, so we shouldn't try to instigate
     *                 a resume here if not null.
     * @param pauseImmediately True if the caller does not want to wait for the activity callback to
     *                         complete pausing.
     * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
     * it to tell us when it is done.
     */
    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);
            }
        }
        ActivityRecord prev = mResumedActivity; // 就是 SecondActivity

        if (prev == null) { // 不进入此分支
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }

        if (prev == resuming) { // false
            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; // mPausingActivity 指向 SecondActivity
        mLastPausedActivity = prev;
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
        // 设置 SecondActivity 的状态,把 ActivityStack 的 mResumedActivity 置为 null。
        prev.setState(PAUSING, "startPausingLocked");
        prev.getTask().touchActiveTime();
        clearLaunchTime(prev);

        mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());

        mService.updateCpuStats();

        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);
				// 调用这里,开始执行转换
                mService.getLifecycleManager().scheduleTransaction(prev.app.thread, 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;
            }
        } else { // 不进入此分支
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }

        // If we are not going to sleep, we want to ensure the device is
        // awake until the next activity is started.
        if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
            mStackSupervisor.acquireLaunchWakelock();
        }

        if (mPausingActivity != null) { // 进入此分支
            // Have the window manager pause its key dispatching until the new
            // activity has started.  If we're pausing the activity just because
            // the screen is being turned off and the UI is sleeping, don't interrupt
            // key dispatch; the same activity will pick it up again on wakeup.
            if (!uiSleeping) {
                prev.pauseKeyDispatchingLocked();
            } else if (DEBUG_PAUSE) {
                 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
            }

            if (pauseImmediately) { // false
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                completePauseLocked(false, resuming);
                return false;

            } else {
                schedulePauseTimeout(prev);
                return true;
            }

        } else { // 不进入此分支
            // This activity failed to schedule the
            // pause, so just treat it as being paused now.
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
            if (resuming == null) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }
    }

2.7.1 PauseActivityItem.obtain() 方法

我们需要看一下 PauseActivityItem 调用静态方法 obtain() 的源码:
PauseActivityItemActivityLifecycleItem 的子类,它的作用是请求把一个 activity 迁移到 paused 状态。

/**
 * Request to move an activity to paused state.
 * @hide
 */
public class PauseActivityItem extends ActivityLifecycleItem {

    private static final String TAG = "PauseActivityItem";

    private boolean mFinished;
    private boolean mUserLeaving;
    private int mConfigChanges;
    private boolean mDontReport;

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

    @Override
    public int getTargetState() {
        return ON_PAUSE;
    }

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


    // ObjectPoolItem implementation

    private PauseActivityItem() {}
	/*
	boolean finished, true,这是在 ActivityRecord.makeFinishingLocked() 方法中修改为 true 的。
	boolean userLeaving, false
	int configChanges, 
    boolean dontReport, false
	*/
    /** Obtain an instance initialized with provided params. */
    public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges,
            boolean dontReport) {
        PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
        if (instance == null) {
            instance = new PauseActivityItem();
        }
        instance.mFinished = finished;
        instance.mUserLeaving = userLeaving;
        instance.mConfigChanges = configChanges;
        instance.mDontReport = dontReport;

        return instance;
    }

    /** Obtain an instance initialized with default params. */
    public static PauseActivityItem obtain() {
        PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
        if (instance == null) {
            instance = new PauseActivityItem();
        }
        instance.mFinished = false;
        instance.mUserLeaving = false;
        instance.mConfigChanges = 0;
        instance.mDontReport = true;

        return instance;
    }

    @Override
    public void recycle() {
        super.recycle();
        mFinished = false;
        mUserLeaving = false;
        mConfigChanges = 0;
        mDontReport = false;
        ObjectPool.recycle(this);
    }

    // Parcelable implementation

    /** Write to Parcel. */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeBoolean(mFinished);
        dest.writeBoolean(mUserLeaving);
        dest.writeInt(mConfigChanges);
        dest.writeBoolean(mDontReport);
    }

    /** Read from Parcel. */
    private PauseActivityItem(Parcel in) {
        mFinished = in.readBoolean();
        mUserLeaving = in.readBoolean();
        mConfigChanges = in.readInt();
        mDontReport = in.readBoolean();
    }

    public static final Creator<PauseActivityItem> CREATOR =
            new Creator<PauseActivityItem>() {
        public PauseActivityItem createFromParcel(Parcel in) {
            return new PauseActivityItem(in);
        }

        public PauseActivityItem[] newArray(int size) {
            return new PauseActivityItem[size];
        }
    };

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final PauseActivityItem other = (PauseActivityItem) o;
        return mFinished == other.mFinished && mUserLeaving == other.mUserLeaving
                && mConfigChanges == other.mConfigChanges && mDontReport == other.mDontReport;
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + (mFinished ? 1 : 0);
        result = 31 * result + (mUserLeaving ? 1 : 0);
        result = 31 * result + mConfigChanges;
        result = 31 * result + (mDontReport ? 1 : 0);
        return result;
    }

    @Override
    public String toString() {
        return "PauseActivityItem{finished=" + mFinished + ",userLeaving=" + mUserLeaving
                + ",configChanges=" + mConfigChanges + ",dontReport=" + mDontReport + "}";
    }
}

2.8 ClientLifecycleManager.scheduleTransaction() 方法

  • @NonNull IApplicationThread client, mMainThread.getApplicationThread()类型转换得到的IApplicationThread对象,
  • @NonNull IBinder activityToken, mToken
  • @NonNull ClientTransactionItem callback, PauseActivityItem 对象
    /**
     * Schedule a single callback delivery to client activity.
     * @param client Target client.
     * @param activityToken Target activity token.
     * @param callback A request to deliver a callback.
     * @throws RemoteException
     *
     * @see ClientTransactionItem
     */
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ClientTransactionItem callback) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken,
                callback);
        scheduleTransaction(clientTransaction);
    }

2.8.1 ClientLifecycleManager.transactionWithState() 方法

  • @NonNull IApplicationThread client, mMainThread.getApplicationThread()类型转换得到的IApplicationThread对象,
  • @NonNull IBinder activityToken, mToken
  • @NonNull ClientTransactionItem callback, PauseActivityItem 对象
  • 返回值 ClientTransaction
    /**
     * @return A new instance of {@link ClientTransaction} with a single lifecycle state request.
     *
     * @see ClientTransaction
     * @see ClientTransactionItem
     */
    private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        // Set the lifecycle state in which the client should be after executing the transaction.
        clientTransaction.setLifecycleStateRequest(stateRequest);
        return clientTransaction;
    }

2.9 ClientLifecycleManager.scheduleTransaction() 方法

    /**
     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
     * @param transaction A sequence of client transaction items.
     * @throws RemoteException
     *
     * @see 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();
        }
    }

2.10 ClientTransaction.schedule() 方法

    /**
     * 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 是 IApplicationThread 类型
        mClient.scheduleTransaction(this);
    }

2.11 ApplicationThread.scheduleTransaction() 方法

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

2.12 ClientTransactionHandler.scheduleTransaction() 方法

ClientTransactionHandlerActivityThread 的基类

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

2.13 ActivityThread.sendMessage() 方法

    void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }
    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) { // false
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

可以看到 mH 的 声明:

 final H mH = new H();

而 H 是一个 Handler 的子类:

    class H extends Handler {

在 H 的 handleMessage() 方法中,可以找到:

                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    // 把传递过来的 ClientTransaction 对象交给 mTransactionExecutor 去执行
                    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;

那么 TransactionExecutor 是什么呢?

    // An executor that performs multi-step transactions.
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

2.14 TransactionExecutor.execute() 方法

    /**
     * Resolve transaction.
     * First all callbacks will be executed in the order they appear in the list. If a callback
     * requires a certain pre- or post-execution state, the client will be transitioned accordingly.
     * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
     * either remain in the initial state, or last state needed by a callback.
     */
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
		// 没有设置 Callback
        executeCallbacks(transaction);

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

2.15 TransactionExecutor.executeLifecycleState() 方法

    /** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
    	// 获取到的其实是 PauseActivityItem 对象
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        log("Resolving lifecycle state: " + lifecycleItem);

        final IBinder token = transaction.getActivityToken();
        // 根据 token,获取对应的 ActivityClientRecord 对象
        // ActivityClientRecord 是 ActivityThread 的内部类
        // 这个方法内部是调用 mActivities.get(token); 而 mActivity 是
        // final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
        // 而添加这个 mActivities 的地方是在 ActivityThread.performLaunchActivity() 方法中。
        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);
    }

2.15.1 TransactionExecutor.cycleToPath() 方法

  • ActivityClientRecord r,
  • int finish, ON_PAUSE
  • boolean excludeLastState,true
    /**
     * Transition the client between states with an option not to perform the last hop in the
     * sequence. This is used when resolving lifecycle state request, when the last transition must
     * be performed with some specific parameters.
     */
    private void cycleToPath(ActivityClientRecord r, int finish,
            boolean excludeLastState) {
        final int start = r.getLifecycleState(); // ON_RESUME
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        // mHelper 是成员变量,private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState); // []
        // path 没有内容,什么都不做
        performLifecycleSequence(r, path);
    }

2.15.2 TransactionExecutorHelper.getLifecyclePath() 方法

贴出一些常量在这里,下面会用到:

    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;
  • int start, ON_RESUME 3
  • int finish, ON_PAUSE 4
  • boolean excludeLastState,true
    /**
     * Calculate the path through main lifecycle states for an activity and fill
     * @link #mLifecycleSequence} with values starting with the state that follows the initial
     * state.
     * <p>NOTE: The returned value is used internally in this class and is not a copy. It's contents
     * may change after calling other methods of this class.</p>
     */
    @VisibleForTesting
    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) { // 4 >= 3, 进入此分支
            // just go there
            for (int i = start + 1; i <= finish; i++) {
                mLifecycleSequence.add(i); // ON_PAUSE
            }
        } 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) { // true
            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
        }

        return mLifecycleSequence; // []
    }

2.16 PauseActivityItem.execute() 方法

/**
 * Request to move an activity to paused state.
 * @hide
 */
public class PauseActivityItem extends ActivityLifecycleItem {

    private static final String TAG = "PauseActivityItem";

    private boolean mFinished;
    private boolean mUserLeaving;
    private int mConfigChanges;
    private boolean mDontReport;
/*
	boolean finished, true,这是在 ActivityRecord.makeFinishingLocked() 方法中修改为 true 的。
	boolean userLeaving, false
	int configChanges, 
    boolean dontReport, false
	*/
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        /*
		token:
		mFinished: true
		mUserLeaving: false
		mConfigChanges:
		pendingActions:
		*/
        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
                "PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

    @Override
    public int getTargetState() {
        return ON_PAUSE;
    }

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


    // ObjectPoolItem implementation

    private PauseActivityItem() {}

    /** Obtain an instance initialized with provided params. */
    public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges,
            boolean dontReport) {
        PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
        if (instance == null) {
            instance = new PauseActivityItem();
        }
        instance.mFinished = finished;
        instance.mUserLeaving = userLeaving;
        instance.mConfigChanges = configChanges;
        instance.mDontReport = dontReport;

        return instance;
    }

    /** Obtain an instance initialized with default params. */
    public static PauseActivityItem obtain() {
        PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
        if (instance == null) {
            instance = new PauseActivityItem();
        }
        instance.mFinished = false;
        instance.mUserLeaving = false;
        instance.mConfigChanges = 0;
        instance.mDontReport = true;

        return instance;
    }

    @Override
    public void recycle() {
        super.recycle();
        mFinished = false;
        mUserLeaving = false;
        mConfigChanges = 0;
        mDontReport = false;
        ObjectPool.recycle(this);
    }

    // Parcelable implementation

    /** Write to Parcel. */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeBoolean(mFinished);
        dest.writeBoolean(mUserLeaving);
        dest.writeInt(mConfigChanges);
        dest.writeBoolean(mDontReport);
    }

    /** Read from Parcel. */
    private PauseActivityItem(Parcel in) {
        mFinished = in.readBoolean();
        mUserLeaving = in.readBoolean();
        mConfigChanges = in.readInt();
        mDontReport = in.readBoolean();
    }

    public static final Creator<PauseActivityItem> CREATOR =
            new Creator<PauseActivityItem>() {
        public PauseActivityItem createFromParcel(Parcel in) {
            return new PauseActivityItem(in);
        }

        public PauseActivityItem[] newArray(int size) {
            return new PauseActivityItem[size];
        }
    };

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final PauseActivityItem other = (PauseActivityItem) o;
        return mFinished == other.mFinished && mUserLeaving == other.mUserLeaving
                && mConfigChanges == other.mConfigChanges && mDontReport == other.mDontReport;
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + (mFinished ? 1 : 0);
        result = 31 * result + (mUserLeaving ? 1 : 0);
        result = 31 * result + mConfigChanges;
        result = 31 * result + (mDontReport ? 1 : 0);
        return result;
    }

    @Override
    public String toString() {
        return "PauseActivityItem{finished=" + mFinished + ",userLeaving=" + mUserLeaving
                + ",configChanges=" + mConfigChanges + ",dontReport=" + mDontReport + "}";
    }
}

3. 最后

参考

发布了78 篇原创文章 · 获赞 46 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/willway_wang/article/details/103689300