Android系统源码分析--Activity的finish过程

1,261 阅读4分钟

上一篇我们分析了Activity的启动流程,由于代码量很大,还是没有分析的很详细,但是基本流程都出来了,更详细的东西还是要去看源码,源码在我文章的最后有给出,里面有我添加的详细的注释。这一章来分析Activity的finish过程,这个问题在两年前我去面试金山的时候曾经被问到过,那时候对源码基本没什么了解,所以当时根本是不了解的,今天我们就来分析一下finish的过程到底做了哪些处理,最后对Activity的整个启动过程以及finish过程绘制流程图,以方便我们记忆。

finish代码分析

首先先贴一张时序图:

Activity的finish方法就是调用的父类的finish方法:

Step1.Activity.finish

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

这里调用finish方法,传入参数DONT_FINISH_TASK_WITH_ACTIVITY,这个参数是在finish掉Activity的时候不finish掉Task。

Step2.Activity.finish

    private void finish(int finishTask) {
        ...
                if (ActivityManagerNative.getDefault()
                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
                    mFinished = true;
                }
        ...
    }

ActivityManagerNative.getDefault()方法其实我们在前面文章提到过,得到的是AMP(ActivityManagerProxy)。

Step3.AMP.finishActivity

    public boolean finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask)
            throws RemoteException {
        ...
        mRemote.transact(FINISH_ACTIVITY_TRANSACTION, data, reply, 0);
        ...
    }

通过Binder调用AMS的finishActivity方法。

Step4.AMS.finishActivity

    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
                                        int finishTask) {
        ...
        synchronized (this) {
            // 根据token(IBinder)获取Activity的对象封装ActivityRecord
            ActivityRecord r = ActivityRecord.isInStackLocked(token);
            if (r == null) {
                return true;
            }
            // Keep track of the root activity of the task before we finish it
            TaskRecord tr = r.task;
            // 从栈底部获取第一没有被finish的Activity对象封装
            ActivityRecord rootR = tr.getRootActivity();
            ...
            if (mController != null) {
                // Find the first activity that is not finishing.
                // 获取第一个没有被回收的Activity
                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
                if (next != null) {
                    ...
                }
            }
            final long origId = Binder.clearCallingIdentity();
            try {
                // 传入的finishTask是DONT_FINISH_TASK_WITH_ACTIVITY,所以下面参数是false
                final boolean finishWithRootActivity =
                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
                // 这里if中条件为false所以走else语句
                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
                        || (finishWithRootActivity && r == rootR)) {
                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
                    ...
                } else {
                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
                            resultData, "app-request", true);
                    ...
                }
                return res;
            } finally {
               ...
            }
        }
    }

上面try语句中会走else语句中的方法也就是ActivityStack.requestFinishActivityLocked

Step5.ActivityStack.requestFinishActivityLocked

    final boolean requestFinishActivityLocked(IBinder token, int resultCode,
                                              Intent resultData, String reason, boolean oomAdj) {
        ActivityRecord r = isInStackLocked(token);
        ...

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

调用finishActivityLocked方法

Step6.ActivityStack.finishActivityLocked

    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
                                       String reason, boolean oomAdj) {
        if (r.finishing) {// 如果要清理的的正在finish,则不需要再清理
            Slog.w(TAG, "Duplicate finish request for " + r);
            return false;
        }

        // 标记开始finish
        r.makeFinishingLocked();
        ...

        // 停止键盘分发事件
        r.pauseKeyDispatchingLocked();

        adjustFocusedActivityLocked(r, "finishActivity");

        finishActivityResultsLocked(r, resultCode, resultData);

        // 如果任务中没有了Activity要结束任务
        final boolean endTask = index <= 0;
        final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
        if (mResumedActivity == r) {// 如果当前显示的Activity就是要结束的Activity

            ...

            if (mPausingActivity == null) {
                // 开始暂停Activity
                startPausingLocked(false, false, null, false);
            }

            if (endTask) {// 如果任务中没有了Activity,则移除任务
                mStackSupervisor.removeLockedTaskLocked(task);
            }
        } else if (r.state != ActivityState.PAUSING) {// 如果要移除的Activity不是Pausing状态并且不是正在显示的Activity
            ...
            return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
                    FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
        } else {
            ...
        }

        return false;
    }

这里首先调用ActivityRecord.makeFinishingLocked标记开始结束Activity,然后调用ActivityRecord.pauseKeyDispatchingLocked方法停止键盘事件分发。然后调用adjustFocusedActivityLocked方法,调整Activity的焦点状体。

Step7.ActivityStack.adjustFocusedActivityLocked

   private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {
        // 如果当前栈没有焦点,或者当前Activity也不是当前有焦点的Activity,返回
        if (!mStackSupervisor.isFocusedStack(this) || mService.mFocusedActivity != r) {
            return;
        }

        // 获取栈顶正在运行的Activity
        final ActivityRecord next = topRunningActivityLocked();
        final String myReason = reason + " adjustFocus";
        if (next != r) {// 如果栈顶正在运行的不是当前要结束的Activity
            if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) {
                mService.setFocusedActivityLocked(next, myReason);
                return;
            } else {
                final TaskRecord task = r.task;
                if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
                    final int taskToReturnTo = task.getTaskToReturnTo();
                    if (!mFullscreen
                            && adjustFocusToNextFocusableStackLocked(taskToReturnTo, myReason)) {
                        return;
                    }
                    if (mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, myReason)) {
                        return;
                    }
                }
            }
        }

        mService.setFocusedActivityLocked(mStackSupervisor.topRunningActivityLocked(), myReason);
    }

当前Activity要finish掉,就找找到下一个应该获取焦点的Activity,在该Activity被finish掉之后显示出来。

Step8.ActivityStack.finishActivityResultsLocked

   final void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
        // send the result
        ActivityRecord resultTo = r.resultTo;
        if (resultTo != null) {
            ...
            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);

        ...
    }

如果要接收Result的Activity描述对象ActivityRecord还存在,就将result相关信息封装成ActivityResult对象放到ActivityResult列表中保存起来。然后置空该Activity对应的ActivityRecord对象中的信息。

Step9.ActivityStack.startPausingLocked

    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
                                     ActivityRecord resuming, boolean dontWait) {
        if (mPausingActivity != null) {
            Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                    + " state=" + mPausingActivity.state);
            if (!mService.isSleepingLocked()) {// 如果没有在睡眠,则完成Pause状态
                completePauseLocked(false, resuming);
            }
        }
        // prev指向源Activity
        ActivityRecord prev = mResumedActivity;
        if (prev == null) {
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }

        if (mActivityContainer.mParentActivity == null) {
            // Top level stack, not a child. Look for child stacks.
            // 暂停所有子栈的Activity
            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
        }

        ...
        // 改变状态
        prev.state = ActivityState.PAUSING;
        ...
        // 获取正在启动的Activity组件
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
        ...

        if (prev.app != null && prev.app.thread != null) {
            ...
                // 通知源Activity组件,暂停源Activity以便有机会执行一些数据保存操作,
                // 这里如果目标sdk<11会调用onSaveInstanceState,然后调用onPause
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            ...
        } else {
            ...
        }

        ...
    }

这里主要是在finish之前pause该Activity,如果状态正常会调用schedulePauseActivity方法,最终调用Activity的onPause方法,这个过程我们在前面讲过几次了,这里就不再分析,比较简单。我们接着看核心的代码。

Step10.ActivityStack.finishCurrentActivityLocked

    final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
        // 如果当前要finish的Activity正在显示,而复用的Activity还没有显示,那么延迟finish,
        // 直到复用Activity显示

        // 获取顶部正在运行的Activity
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();

        // 如果是显示后在finish,并且要结束的正在显示或者将要显示,并且顶部运行的存在而且没有显示
        if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
                && next != null && !next.nowVisible) {
            // 如果当前要结束的Activity不在正在停止列表中则添加到停止列表中
            if (!mStackSupervisor.mStoppingActivities.contains(r)) {
                addToStopping(r, false /* immediate */);
            }
            ...
            return r;
        }

        // make sure the record is cleaned out of other places.
        // 从各个列表中清理这个将要被finish的Activity
        ...
        final ActivityState prevState = r.state;// 存储清理之前的状态
        r.state = ActivityState.FINISHING;// 设置为正在finish状态
        // 判断当前正在清理的Activity是否在当前获取焦点的栈中
        final boolean finishingActivityInNonFocusedStack
                = r.task.stack != mStackSupervisor.getFocusedStack()
                && prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;

        if (mode == FINISH_IMMEDIATELY
                || (prevState == ActivityState.PAUSED
                && (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID))
                || finishingActivityInNonFocusedStack
                || prevState == ActivityState.STOPPED
                || prevState == ActivityState.INITIALIZING) {
            ...
            // 销毁Activity
            boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");

            ...
            return activityRemoved ? null : r;
        }

        ...
        return r;
    }

这里是开始销毁Activity,首先要保存状态,然后标记开始finish,然后调用destroyActivityLocked方法开始销毁。

Step11.ActivityStack.destroyActivityLocked

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

        // 清理Activity
        cleanUpActivityLocked(r, false, false);

        final boolean hadApp = r.app != null;

        if (hadApp) {
           ...

            boolean skipDestroy = false;

            try {
                r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
                        r.configChangeFlags);
            } catch (Exception e) {
                ...
            }

            ...

        return removedFromHistory;
    }

这里主要有两部操作,第一步是cleanUpActivityLocked,第二步是scheduleDestroyActivity。我们先看第一步。

Step12.ActivityStack.cleanUpActivityLocked

    final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices,
                                     boolean setState) {
        if (mResumedActivity == r) {
            mResumedActivity = null;
        }
        if (mPausingActivity == r) {
            mPausingActivity = null;
        }
        mService.resetFocusedActivityIfNeededLocked(r);

        ...

        // Make sure this record is no longer in the pending finishes list.
        // This could happen, for example, if we are trimming activities
        // down to the max limit while they are still waiting to finish.
        mStackSupervisor.mFinishingActivities.remove(r);
        mStackSupervisor.mWaitingVisibleActivities.remove(r);

        ...

        if (cleanServices) {// 是否清理服务
            cleanUpActivityServicesLocked(r);
        }

        ...
    }

这里主要是将指向该销毁的Activity的引用都置空,进行释放,然后将该Activity描述对象从列表中移除该对象,最后是判断是否清理服务,其实主要是绑定该Activity的服务,如果有绑定则解除绑定。

Step13.ActivityManagerService.resetFocusedActivityIfNeededLocked

    // 重新设置获取焦点的Activity,如果被清理的不是获取焦点的,那么不处理,否则将焦点移动到另外一个Activity
    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
        ...

        // Try to move focus to another activity if possible.
        // 如果允许,将焦点移动到另外一个Activity
        if (setFocusedActivityLocked(
                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
            return;
        }

        ...
    }

这里调用setFocusedActivityLocked方法判断该Activity是不是允许允许将焦点移除。

Step14.ActivityManagerService.setFocusedActivityLocked

    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
        if (r == null || mFocusedActivity == r) {// 如果传入的焦点Activity不存在或者就是显示在有焦点的Activity则不需要处理了
            return false;
        }

        if (!r.isFocusable()) {// 如果没有获取焦点,返回
            return false;
        }

        ...

        // 获取之前有焦点的Activity
        final ActivityRecord last = mFocusedActivity;
        mFocusedActivity = r;// 设置传入的Activity为当前焦点Activity
        if (r.task.isApplicationTask()) {// 当前焦点Activity所在任务是应用任务(不是桌面和最近应用界面)
            if (mCurAppTimeTracker != r.appTimeTracker) {
                ...
            } else {
                startTimeTrackingFocusedActivityLocked();
            }
        } else {
            r.appTimeTracker = null;
        }
        ...
        // 将要启动的Activity移动到前台
        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
            mWindowManager.setFocusedApp(r.appToken, true);
        }
        ...
        return true;
    }

这里看一下注释,主要是判断该Activity是否有焦点,是否允许切换焦点。因此要结束的Activity就要把焦点释放掉。

Step15.ActivityStack.cleanUpActivityServicesLocked

    final void cleanUpActivityServicesLocked(ActivityRecord r) {
        // Throw away any services that have been bound by this activity.
        if (r.connections != null) {
            Iterator<ConnectionRecord> it = r.connections.iterator();
            while (it.hasNext()) {
                ConnectionRecord c = it.next();
                mService.mServices.removeConnectionLocked(c, null, r);
            }
            r.connections = null;
        }
    }

上面我们提到这个方法主要是释放绑定的服务,如果没有则不需要释放。下面我们回到Step11中提到的第二步。

Step16.ApplicationThreadNative.scheduleDestroyActivity

    public final void scheduleDestroyActivity(IBinder token, boolean finishing,
            int configChanges) throws RemoteException {
        ...
        mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        ..
    }

这个很熟悉了。

Step17.ApplicationThread.scheduleDestroyActivity

        public final void scheduleDestroyActivity(IBinder token, boolean finishing,
                                                  int configChanges) {
            sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
                    configChanges);
        }

通过发送消息到Handler中来处理。

Step18.ActivityThread.H.handleMessage

        public void handleMessage(Message msg) {
            switch (msg.what) {
            ...
                case DESTROY_ACTIVITY:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
                    handleDestroyActivity((IBinder) msg.obj, msg.arg1 != 0,
                            msg.arg2, false);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
            ...

Step19.ActivityThread.handleDestroyActivity

    private void handleDestroyActivity(IBinder token, boolean finishing,
                                       int configChanges, boolean getNonConfigInstance) {
        ActivityClientRecord r = performDestroyActivity(token, finishing,
                configChanges, getNonConfigInstance);
        ...
        if (finishing) {
            try {
                ActivityManagerNative.getDefault().activityDestroyed(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
        mSomeActivitiesChanged = true;
    }

Step20.ActivityThread.performDestroyActivity

    private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
                                                        int configChanges, boolean getNonConfigInstance) {
        ActivityClientRecord r = mActivities.get(token);
        Class<? extends Activity> activityClass = null;
        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
        if (r != null) {
            ...

            performPauseActivityIfNeeded(r, "destroy");

            ...
            
            try {
                r.activity.mCalled = false;
                mInstrumentation.callActivityOnDestroy(r.activity);
                ...
            } catch (SuperNotCalledException e) {
                throw e;
            } catch (Exception e) {
                ...
            }
        }
        ...
        return r;
    }

执行performPauseActivityIfNeeded,然后执行Instrumentation.callActivityOnDestroy方法结束。

Step21.ActivityThread.performPauseActivityIfNeeded

    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        if (r.paused) {
            // You are already paused silly...
            return;
        }

        try {
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnPause(r.activity);
            ...
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            ...
        }
        r.paused = true;
    }

如果已经paused了,则直接返回,否则调用Instrumentation.callActivityOnPause方法。

Step22.Instrumentation.callActivityOnPause

    public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }

Step23.Activity.performPause

    final void performPause() {
        ..
        onPause();
        ...
    }

Step24.Activity.onPause

    protected void onPause() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);
        getApplication().dispatchActivityPaused(this);
        mCalled = true;
    }

这里就是调用了Activity的onPause方法了。

Step25.Activity.performStop

    final void performStop(boolean preserveWindow) {
        ...

        if (!mStopped) {
            ...

            mCalled = false;
            mInstrumentation.callActivityOnStop(this);
            ...
        }
        mResumed = false;
    }

这里调用Instrumentation.callActivityOnStop方法,这里本来还有Fragment的处理,我略掉了,自己看看。

Step26.Instrumentation.callActivityOnStop

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

这里调用了Activity的onStop方法。代码略了。

Step28.Instrumentation.callActivityOnDestroy

    public void callActivityOnDestroy(Activity activity) {
      ...
      
      activity.performDestroy();
      
      ...
   }

调用Activity的performDestroy方法

Step29.Activity.performDestroy

    final void performDestroy() {
        ...
        onDestroy();
        ...
    }

这里终于看到了onDestroy方法。这里还有Fragment的处理,我没有显示出来,自己看看。我们再回到Step20中的第二个方法中。

Step31.AMP.activityDestroyed

    public void activityDestroyed(IBinder token) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        mRemote.transact(ACTIVITY_DESTROYED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

然后调用AMS中的activityDestroyed方法。

Step32.AMS.activityDestroyed

    public final void activityDestroyed(IBinder token) {
        synchronized (this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityDestroyedLocked(token, "activityDestroyed");
            }
        }
    }

Step33.ActivityStack.activityDestroyedLocked

    final void activityDestroyedLocked(IBinder token, String reason) {
        final long origId = Binder.clearCallingIdentity();
        try {
            ActivityRecord r = ActivityRecord.forTokenLocked(token);
            ...

            if (isInStackLocked(r) != null) {
                if (r.state == ActivityState.DESTROYING) {
                    cleanUpActivityLocked(r, true, false);
                    removeActivityFromHistoryLocked(r, null, reason);
                }
            }
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

这里主要是两步,第一个是调用cleanUpActivityLocked方法,清理Activity,前面Step12我们分析过了,不再分析。然后是调用removeActivityFromHistoryLocked方法,就是将该结束的Activity从历史列表中删除.

Step35.ActivityStack.removeActivityFromHistoryLocked

    // 从历史记录移除
    private void removeActivityFromHistoryLocked(
            ActivityRecord r, TaskRecord oldTop, String reason) {
        mStackSupervisor.removeChildActivityContainers(r);
        finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
        ...
        if (task != null && task.removeActivity(r)) {
            if (mStackSupervisor.isFocusedStack(this) && task == topTask &&
                    task.isOverHomeStack()) {
                mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason);
            }
            removeTask(task, reason);
        }
        cleanUpActivityServicesLocked(r);
        r.removeUriPermissionsLocked();
    }

调用finishActivityResultsLocked方法处理Result,前面提到了。调用ActivityStackSupervisor.moveHomeStackTaskToTop将Home属性的Activity所在任务栈放到顶部。调用cleanUpActivityServicesLocked清理绑定的服务。

Step39.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

    boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }

这里我们在上一章Activity的启动时已经分析过了。这里不再分析。到这里Activity的finish就分析完了,从这里我们主要学到的是finish的过程,以及finish过程中系统做了哪些处理,我们在写代码过程中应该做那些处理。

流程图:

代码地址:

直接拉取导入开发工具(Intellij idea或者Android studio)

Android_Framework_Source

注:

微信公众账号:Code-MX

注:本文原创,转载请注明出处,多谢。