Android系統(tǒng)源碼分析--Activity的finish過程

上一篇我們分析了Activity的啟動流程忌愚,由于代碼量很大,還是沒有分析的很詳細(xì)却邓,但是基本流程都出來了硕糊,更詳細(xì)的東西還是要去看源碼,源碼在我文章的最后有給出腊徙,里面有我添加的詳細(xì)的注釋简十。這一章來分析Activity的finish過程,這個問題在兩年前我去面試金山的時候曾經(jīng)被問到過撬腾,那時候?qū)υ创a基本沒什么了解螟蝙,所以當(dāng)時根本是不了解的,今天我們就來分析一下finish的過程到底做了哪些處理民傻,最后對Activity的整個啟動過程以及finish過程繪制流程圖胰默,以方便我們記憶。

finish代碼分析

首先先貼一張時序圖:

ActivityFinish.jpg

Activity的finish方法就是調(diào)用的父類的finish方法:

Step1.Activity.finish

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

這里調(diào)用finish方法漓踢,傳入?yún)?shù)DONT_FINISH_TASK_WITH_ACTIVITY牵署,這個參數(shù)是在finish掉Activity的時候不finish掉Task。

Step2.Activity.finish

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

ActivityManagerNative.getDefault()方法其實(shí)我們在前面文章提到過喧半,得到的是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調(diào)用AMS的finishActivity方法。

Step4.AMS.finishActivity

    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
                                        int finishTask) {
        ...
        synchronized (this) {
            // 根據(jù)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挺据,所以下面參數(shù)是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;
    }

調(diào)用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;
        }

        // 標(biāo)記開始finish
        r.makeFinishingLocked();
        ...

        // 停止鍵盤分發(fā)事件
        r.pauseKeyDispatchingLocked();

        adjustFocusedActivityLocked(r, "finishActivity");

        finishActivityResultsLocked(r, resultCode, resultData);

        // 如果任務(wù)中沒有了Activity要結(jié)束任務(wù)
        final boolean endTask = index <= 0;
        final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
        if (mResumedActivity == r) {// 如果當(dāng)前顯示的Activity就是要結(jié)束的Activity

            ...

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

            if (endTask) {// 如果任務(wù)中沒有了Activity,則移除任務(wù)
                mStackSupervisor.removeLockedTaskLocked(task);
            }
        } else if (r.state != ActivityState.PAUSING) {// 如果要移除的Activity不是Pausing狀態(tài)并且不是正在顯示的Activity
            ...
            return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
                    FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
        } else {
            ...
        }

        return false;
    }

這里首先調(diào)用ActivityRecord.makeFinishingLocked標(biāo)記開始結(jié)束Activity扁耐,然后調(diào)用ActivityRecord.pauseKeyDispatchingLocked方法停止鍵盤事件分發(fā)暇检。然后調(diào)用adjustFocusedActivityLocked方法,調(diào)整Activity的焦點(diǎn)狀體做葵。

Step7.ActivityStack.adjustFocusedActivityLocked

   private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {
        // 如果當(dāng)前棧沒有焦點(diǎn)占哟,或者當(dāng)前Activity也不是當(dāng)前有焦點(diǎn)的Activity,返回
        if (!mStackSupervisor.isFocusedStack(this) || mService.mFocusedActivity != r) {
            return;
        }

        // 獲取棧頂正在運(yùn)行的Activity
        final ActivityRecord next = topRunningActivityLocked();
        final String myReason = reason + " adjustFocus";
        if (next != r) {// 如果棧頂正在運(yùn)行的不是當(dāng)前要結(jié)束的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);
    }

當(dāng)前Activity要finish掉酿矢,就找找到下一個應(yīng)該獲取焦點(diǎn)的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相關(guān)信息封裝成ActivityResult對象放到ActivityResult列表中保存起來蜜暑。然后置空該Activity對應(yīng)的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狀態(tài)
                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);
        }

        ...
        // 改變狀態(tài)
        prev.state = ActivityState.PAUSING;
        ...
        // 獲取正在啟動的Activity組件
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
        ...

        if (prev.app != null && prev.app.thread != null) {
            ...
                // 通知源Activity組件肛捍,暫停源Activity以便有機(jī)會執(zhí)行一些數(shù)據(jù)保存操作隐绵,
                // 這里如果目標(biāo)sdk<11會調(diào)用onSaveInstanceState,然后調(diào)用onPause
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            ...
        } else {
            ...
        }

        ...
    }

這里主要是在finish之前pause該Activity拙毫,如果狀態(tài)正常會調(diào)用schedulePauseActivity方法依许,最終調(diào)用Activity的onPause方法,這個過程我們在前面講過幾次了缀蹄,這里就不再分析峭跳,比較簡單。我們接著看核心的代碼缺前。

Step10.ActivityStack.finishCurrentActivityLocked

    final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
        // 如果當(dāng)前要finish的Activity正在顯示蛀醉,而復(fù)用的Activity還沒有顯示,那么延遲finish衅码,
        // 直到復(fù)用Activity顯示

        // 獲取頂部正在運(yùn)行的Activity
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();

        // 如果是顯示后在finish拯刁,并且要結(jié)束的正在顯示或者將要顯示,并且頂部運(yùn)行的存在而且沒有顯示
        if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
                && next != null && !next.nowVisible) {
            // 如果當(dāng)前要結(jié)束的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;// 存儲清理之前的狀態(tài)
        r.state = ActivityState.FINISHING;// 設(shè)置為正在finish狀態(tài)
        // 判斷當(dāng)前正在清理的Activity是否在當(dāng)前獲取焦點(diǎn)的棧中
        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逝段,首先要保存狀態(tài)垛玻,然后標(biāo)記開始finish,然后調(diào)用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) {// 是否清理服務(wù)
            cleanUpActivityServicesLocked(r);
        }

        ...
    }

這里主要是將指向該銷毀的Activity的引用都置空,進(jìn)行釋放参淹,然后將該Activity描述對象從列表中移除該對象醉锄,最后是判斷是否清理服務(wù),其實(shí)主要是綁定該Activity的服務(wù)浙值,如果有綁定則解除綁定恳不。

Step13.ActivityManagerService.resetFocusedActivityIfNeededLocked

    // 重新設(shè)置獲取焦點(diǎn)的Activity,如果被清理的不是獲取焦點(diǎn)的开呐,那么不處理烟勋,否則將焦點(diǎn)移動到另外一個Activity
    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
        ...

        // Try to move focus to another activity if possible.
        // 如果允許,將焦點(diǎn)移動到另外一個Activity
        if (setFocusedActivityLocked(
                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
            return;
        }

        ...
    }

這里調(diào)用setFocusedActivityLocked方法判斷該Activity是不是允許允許將焦點(diǎn)移除筐付。

Step14.ActivityManagerService.setFocusedActivityLocked

    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
        if (r == null || mFocusedActivity == r) {// 如果傳入的焦點(diǎn)Activity不存在或者就是顯示在有焦點(diǎn)的Activity則不需要處理了
            return false;
        }

        if (!r.isFocusable()) {// 如果沒有獲取焦點(diǎn)卵惦,返回
            return false;
        }

        ...

        // 獲取之前有焦點(diǎn)的Activity
        final ActivityRecord last = mFocusedActivity;
        mFocusedActivity = r;// 設(shè)置傳入的Activity為當(dāng)前焦點(diǎn)Activity
        if (r.task.isApplicationTask()) {// 當(dāng)前焦點(diǎn)Activity所在任務(wù)是應(yīng)用任務(wù)(不是桌面和最近應(yīng)用界面)
            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是否有焦點(diǎn)瓦戚,是否允許切換焦點(diǎn)沮尿。因此要結(jié)束的Activity就要把焦點(diǎn)釋放掉。

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

上面我們提到這個方法主要是釋放綁定的服務(wù)较解,如果沒有則不需要釋放畜疾。下面我們回到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);
        }

通過發(fā)送消息到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;
    }

執(zhí)行performPauseActivityIfNeeded姥敛,然后執(zhí)行Instrumentation.callActivityOnDestroy方法結(jié)束。

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

如果已經(jīng)paused了瞎暑,則直接返回徒溪,否則調(diào)用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;
    }

這里就是調(diào)用了Activity的onPause方法了金顿。

Step25.Activity.performStop

    final void performStop(boolean preserveWindow) {
        ...

        if (!mStopped) {
            ...

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

這里調(diào)用Instrumentation.callActivityOnStop方法,這里本來還有Fragment的處理鲤桥,我略掉了揍拆,自己看看。

Step26.Instrumentation.callActivityOnStop

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

這里調(diào)用了Activity的onStop方法茶凳。代碼略了嫂拴。

Step28.Instrumentation.callActivityOnDestroy

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

調(diào)用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();
    }

然后調(diào)用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);
        }
    }

這里主要是兩步,第一個是調(diào)用cleanUpActivityLocked方法谓形,清理Activity灶伊,前面Step12我們分析過了,不再分析寒跳。然后是調(diào)用removeActivityFromHistoryLocked方法聘萨,就是將該結(jié)束的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();
    }

調(diào)用finishActivityResultsLocked方法處理Result,前面提到了童太。調(diào)用ActivityStackSupervisor.moveHomeStackTaskToTop將Home屬性的Activity所在任務(wù)棧放到頂部米辐。調(diào)用cleanUpActivityServicesLocked清理綁定的服務(wù)。

Step39.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

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

這里我們在上一章Activity的啟動時已經(jīng)分析過了书释。這里不再分析翘贮。到這里Activity的finish就分析完了,從這里我們主要學(xué)到的是finish的過程爆惧,以及finish過程中系統(tǒng)做了哪些處理择膝,我們在寫代碼過程中應(yīng)該做那些處理。

流程圖:

ActivityFlow.jpg

代碼地址:

直接拉取導(dǎo)入開發(fā)工具(Intellij idea或者Android studio)

Android_Framework_Source

首發(fā)地址:http://www.codemx.cn

Android開發(fā)群:192508518

微信公眾賬號:Code-MX

注:本文原創(chuàng)检激,轉(zhuǎn)載請注明出處肴捉,多謝腹侣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市齿穗,隨后出現(xiàn)的幾起案子傲隶,更是在濱河造成了極大的恐慌,老刑警劉巖窃页,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跺株,死亡現(xiàn)場離奇詭異,居然都是意外死亡脖卖,警方通過查閱死者的電腦和手機(jī)乒省,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畦木,“玉大人袖扛,你說我怎么就攤上這事∈” “怎么了蛆封?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勾栗。 經(jīng)常有香客問我惨篱,道長围俘,這世上最難降的妖魔是什么砸讳? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮界牡,結(jié)果婚禮上绣夺,老公的妹妹穿的比我還像新娘。我一直安慰自己欢揖,他們只是感情好陶耍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著她混,像睡著了一般烈钞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坤按,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天毯欣,我揣著相機(jī)與錄音,去河邊找鬼臭脓。 笑死酗钞,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砚作,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼窘奏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了葫录?” 一聲冷哼從身側(cè)響起着裹,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎米同,沒想到半個月后骇扇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡面粮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年少孝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熬苍。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡稍走,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出冷溃,到底是詐尸還是另有隱情,我是刑警寧澤梦裂,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布似枕,位于F島的核電站,受9級特大地震影響年柠,放射性物質(zhì)發(fā)生泄漏凿歼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一冗恨、第九天 我趴在偏房一處隱蔽的房頂上張望答憔。 院中可真熱鬧,春花似錦掀抹、人聲如沸虐拓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蓉驹。三九已至,卻和暖如春揪利,著一層夾襖步出監(jiān)牢的瞬間态兴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工疟位, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞻润,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像绍撞,于是被迫代替她去往敵國和親正勒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容