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

上一篇我们分析了Activity的启动流程,由于代码量很大,还是没有分析的很详细,但是基本流程都出来了,更详细的东西还是要去看源码。这一章来分析Activity的finish过程,分析一下finish的过程到底做了哪些处理,最后对Activity的整个启动过程以及finish过程绘制流程图,以方便我们记忆。

finish代码分析

// /frameworks/base/core/java/android/app/Activity.java    
    /**
     * Call this when your activity is done and should be closed.  The
     * ActivityResult is propagated back to whoever launched you via
     * onActivityResult().
     */
    public void finish() {
        finish(DONT_FINISH_TASK_WITH_ACTIVITY);
    }

调用的finish函数中的参数可以传如下值:

    /** @hide Task isn't finished when activity is finished */
    public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
    /**
     * @hide Task is finished if the finishing activity is the root of the task. To preserve the
     * past behavior the task is also removed from recents.
     */
    public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
    /**
     * @hide Task is finished along with the finishing activity, but it is not removed from
     * recents.
     */
    public static final int FINISH_TASK_WITH_ACTIVITY = 2;

根据注释,可知各个参数值的意义如下:

  • DONT_FINISH_TASK_WITH_ACTIVITY:销毁activity的时候不销毁task
  • FINISH_TASK_WITH_ROOT_ACTIVITY:如果要销毁的activity是task的根Activity,则将activity所在的task也结束并从最近task中移除
  • FINISH_TASK_WITH_ACTIVITY:无论什么情况,只要销毁activity,就将Activity所在的task也结束

接下来就来分析一下这个finish函数的流程。上文已经提到了finish函数的源码,调用的是一个带参的finish函数:

// frameworks/base/core/java/android/app/Activity.java
    /**
     * Finishes the current activity and specifies whether to remove the task associated with this
     * activity.
     */
    private void finish(int finishTask) {
        if (mParent == null) { //mParent = null
            int resultCode;
            Intent resultData;
            synchronized (this) {
                resultCode = mResultCode;
                resultData = mResultData;
            }
            if (false) Log.v(TAG, "Finishing self: token=" + mToken);
            try {
                if (resultData != null) {
                    resultData.prepareToLeaveProcess(this);
                }
                //调用AMS的finishActivity方法
                if (ActivityManager.getService()
                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
                    mFinished = true; //【此操作很关键,很多生命周期流程都有对该变量的判断】
                }
            } catch (RemoteException e) {
                // Empty
            }
        } else {
            mParent.finishFromChild(this);
        }
 
       ...//是否自动填充的判断处理
    }

跨进程调用AMS.finishActivity函数:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java	
    /**
     * 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
        
        synchronized(this) {
            ActivityRecord r = ActivityRecord.isInStackLocked(token); //【r为当前要finish的activity】
            if (r == null) {
                return true;
            }
            // Keep track of the root activity of the task before we finish it
            TaskRecord tr = r.getTask(); //【获取当前要销毁的Activity所在的Task】
            ActivityRecord rootR = tr.getRootActivity(); //【rootR为即将要finish的Activity所在的task的根Activity(默认task的根Activity指的是在AndroidManifest.xml中定义的<action android:name="android.intent.action.MAIN" />;如果使用singleInstance模式启动则task只有该Activity,根Activity=null)】
            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;
            }
 
            if (mController != null) { //【mController通常情况都为null】
                ... //如果存在下一个resume的activity,则调用IActivityController.activityResuming进行通知
            }
            final long origId = Binder.clearCallingIdentity();
            try {
                boolean res;
                final boolean finishWithRootActivity =
                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
                //【因为finishTask =DONT_FINISH_TASK_WITH_ACTIVITY,该条件不满足】
                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
                        || (finishWithRootActivity && r == rootR)) { 
                    ...
                } else {
                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
                            resultData, "app-request", true); //【关键操作】调用ActivityStack函数销毁activity
                    if (!res) {
                        Slog.i(TAG, "Failed to finish by app-request");
                    }
                }
                return res;
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }
    }

可以看到关键操作是调用ActiivtyStack.requestFinishActivityLocked函数,所以接下来看看这个函数:

// /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java	
    /**
     * @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) {
        ActivityRecord r = isInStackLocked(token); //【r即是将要销毁的activity】
        
        if (r == null) {
            return false;
        }
 
        finishActivityLocked(r, resultCode, resultData, reason, oomAdj); //【==关键操作】
        return true;
    }

可见,关键操作是调用ActivityStack.finishActivityLocked函数

// /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java    
    /**
     * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
     */
    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
            String reason, boolean oomAdj) {
        return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
    }
 
    /**
     * @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) { //【当前是否为finishing状态,r.finishing=false】
            Slog.w(TAG, "Duplicate finish request for " + r);
            return false;
        }
 
        mWindowManager.deferSurfaceLayout(); //【暂停布局】
        try {
            r.makeFinishingLocked(); //【通知task栈中有变化,会设置r.finish=true】
            final TaskRecord task = r.getTask();
            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
                    r.userId, System.identityHashCode(r),
                    task.taskId, r.shortComponentName, reason);
            final ArrayList<ActivityRecord> activities = task.mActivities; //【获取task中的activity】
            final int index = activities.indexOf(r);
            if (index < (activities.size() - 1)) {
                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();
 
            adjustFocusedActivityStack(r, "finishActivity"); //【调整activity栈】
 
            finishActivityResultsLocked(r, resultCode, resultData); //【Activity的销毁结果】
 
            final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
            final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
            if (mResumedActivity == r) { //【mResumedActivity就是当前正要销毁的activity,该条件满足】
                ...
                if (endTask) { //【endTask=false】
                    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) { //【mPausingActivity=null】
                    ...
                    //执行pausing流程,最终也会调用下面的finishCurrentActivityLocked方法
                    startPausingLocked(false, false, null, pauseImmediately);
                }
 
                if (endTask) { //【endTask=false】
                    mService.getLockTaskController().clearLockedTask(task);
                }
            } else if (!r.isState(PAUSING)) {//【条件不满足,不执行】
                ...
                //如果当前要销毁的activity不是mResumedActivity,则直接finish该activity
final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj,
                        "finishActivityLocked") == null;
                return removedActivity;
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
            }
 
            return false;
        } finally {
            mWindowManager.continueSurfaceLayout(); //【继续布局,至此,finish函数执行完毕】
        }
    }

该函数主要完成的事情:

1. 先判断当前是否为finishing状态,如果是, 则直接返回;

2. 如果当前不是finishing状态,则先暂停布局(deferSurfaceLayout),通知Task Stack有变化(ActivityRecord.makeFinishingLocked);

3. 获取Activity的finish结果(finishActivityResultsLocked

4. 如果当前在前台的Activity与要销毁的activity一致,且当前没有正在pausing的activity,则进行pause操作(startPausingLocked);

5.最后,继续布局(continueSurfaceLayout)。到此处,finish函数中的同步操作就执行完毕了。

  • 先来看看ActivityRecord.makeFinishingLocked函数:
///frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
 
   void makeFinishingLocked() {
        if (finishing) { //【finishing = false】
            return;
        }
        finishing = true;
        if (stopped) { //【stopped=false】
            clearOptionsLocked();
        }
 
        if (service != null) { //【service即是AMS,不为null】
            service.mTaskChangeNotificationController.notifyTaskStackChanged();
        }
    }
  • 接着看看finishActivityResultsLocked函数
 /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java    
    private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
        // send the result
        ActivityRecord resultTo = r.resultTo;
        if (resultTo != null) { //【resultTo = null,不执行】
            ...
            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);
            }
            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;
    }
  • 最后看看ActivityStack.startPausingLocked函数:
///frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
    /**
     * 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;
 
        if (prev == null) { //【prev即是将要销毁的activity,不为null】
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }
 
        if (prev == resuming) { //【resuming=null】
            Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
            return false;
        }
 
        mPausingActivity = prev; //【为mPausingActivity赋值】
        mLastPausedActivity = prev;//【为mLastPausedActivity赋值】
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
        prev.setState(PAUSING, "startPausingLocked"); //【设置当前要销毁的activity的状态为PAUSING】
        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);
                //【执行activity的pausing过程】
                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 {
           ...
        }
 
        ....//【休眠情况处理】
 
        if (mPausingActivity != null) { //【上文进行了赋值,mPausingActivity即是要销毁的activity,如果pausing流程执行成功,则该值不为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) { //【uiSleeping=false】
                prev.pauseKeyDispatchingLocked();
            } 
            //是否立即完成pausing过程,此处【pauseImmediately=!ActivityStackSupervisor#PAUSE_IMMEDIATELY=false】
            if (pauseImmediately) {//不执行
                ...
                completePauseLocked(false, resuming);
                return false;
            } else {//延迟执行,最终还是会调用上面的completePauseLocked方法
                schedulePauseTimeout(prev); //【设置超时时间】
                return true;
            }
 
        } else {
            ...
            return false;
        }
    }

 

可以看到,这个函数里有两个关键操作:

  1. ClientLifecycleManager.scheduleTransaction:将PauseActivityItem设置给ClientTransaction对象
  2. ActivityStack.schedulePauseTimeout:设置pause超时时间

☆ scheduleTransaction流程

具体的scheduleTransaction过程可以看 https://blog.csdn.net/a2923790861/article/details/108711598

 这里放一张类图:

以及流程图:

 ☆ shedulePauseTimeout函数

 

    // How long we wait until giving up on the last activity to pause.  This
    // is short because it directly impacts the responsiveness of starting the
    // next activity.
    private static final int PAUSE_TIMEOUT = 500;
 
	/**
     * Schedule a pause timeout in case the app doesn't respond. We don't give it much time because
     * this directly impacts the responsiveness seen by the user.
     */
    private void schedulePauseTimeout(ActivityRecord r) {
        final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
        msg.obj = r;
        r.pauseTime = SystemClock.uptimeMillis();
        mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); //【发送500ms的延时消息PAUSE_TIMEOUT_MSG】
    }


>ActivityStack.java

    private class ActivityStackHandler extends Handler {

        ActivityStackHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case PAUSE_TIMEOUT_MSG: {
                    ActivityRecord r = (ActivityRecord)msg.obj;
                    // We don't at this point know if the activity is fullscreen,
                    // so we need to be conservative and assume it isn't.
                    Slog.w(TAG, "Activity pause timeout for " + r);
                    synchronized (mService) {
                        if (r.app != null) {
                            mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
                        }
                        //延迟操作时间到了之后,查看pausing过程情况
                        activityPausedLocked(r.appToken, true);
                    }
                } break;
                ......
            }
        }
    }

在Activity的pausing过程执行完毕以后,需要执行后续的finish操作,到ActivityStack#activityPausedLocked方法

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

        final ActivityRecord r = isInStackLocked(token);//r !=null
        if (r != null) {
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            //如果pausing执行成功,则此时mPausingActivity即是要销毁的activity==r
            if (mPausingActivity == r) {
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                mService.mWindowManager.deferSurfaceLayout();
                try {
                    //完成pausing过程,最终还是调用下面的finishCurrentActivityLocked方法
                    completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
                } finally {
                    mService.mWindowManager.continueSurfaceLayout();
                }
                return;
            } else {//不执行
                                EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                        r.userId, System.identityHashCode(r), r.shortComponentName,
                        mPausingActivity != null
                            ? mPausingActivity.shortComponentName : "(none)");
                if (r.isState(PAUSING)) {
                    r.setState(PAUSED, "activityPausedLocked");
                    if (r.finishing) {
                        if (DEBUG_PAUSE) Slog.v(TAG,
                                "Executing finish of failed to pause activity: " + r);
                        //pausing过程失败,finish掉activity
                        finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false,
                                "activityPausedLocked");
                    }
                }
            }
        }
        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }

调用了completePauseLocked方法

    private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
        //此时mPausingActivity即是要销毁的activity!=null
        if (prev != null) {
            prev.setWillCloseOrEnterPip(false);
            final boolean wasStopping = prev.isState(STOPPING);
            prev.setState(PAUSED, "completePausedLocked");
            //在finishActivityLocked方法中,调用了要销毁的activity的makeFinishingLocked()方法。所以prev.finishing=true
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                //【finish当前activity】
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
                        "completedPausedLocked");
            } else if (prev.app != null) {//不执行
                ....
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
                prev = null;
            }
            // It is possible the activity was freezing the screen before it was paused.
            // In that case go ahead and remove the freeze this activity has on the screen
            // since it is no longer visible.
            if (prev != null) {
                prev.stopFreezingScreenLocked(true /*force*/);
            }
            mPausingActivity = null;
        }

        ....
    }
    final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,
            String reason) {
        // First things first: if this activity is currently visible,
        // and the resumed activity is not yet visible, then hold off on
        // finishing until the resumed one becomes visible.

        // The activity that we are finishing may be over the lock screen. In this case, we do not
        // want to consider activities that cannot be shown on the lock screen as running and should
        // proceed with finishing the activity if there is no valid next top running activity.
        
        // 获取顶部正在运行的Activity
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(
                true /* considerKeyguardState */);

        if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
                && next != null && !next.nowVisible) {
            // 如果当前要结束的Activity不在正在停止列表中则添加到停止列表中
            if (!mStackSupervisor.mStoppingActivities.contains(r)) {
                addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */);
            }
            if (DEBUG_STATES) Slog.v(TAG_STATES,
                    "Moving to STOPPING: "+ r + " (finish requested)");
            r.setState(STOPPING, "finishCurrentActivityLocked");
            if (oomAdj) {
                mService.updateOomAdjLocked();
            }
            return r;
        }

        // make sure the record is cleaned out of other places.
        // 从各个列表中清理这个将要被finish的Activity
        mStackSupervisor.mStoppingActivities.remove(r);
        mStackSupervisor.mGoingToSleepActivities.remove(r);
        mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(r);
        final ActivityState prevState = r.getState();// 存储清理之前的状态
        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);

        r.setState(FINISHING, "finishCurrentActivityLocked");// 设置为正在finish状态
        // 判断当前正在清理的Activity是否在当前获取焦点的栈中
        final boolean finishingActivityInNonFocusedStack
                = r.getStack() != mStackSupervisor.getFocusedStack()
                && prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;

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

            ......
            return activityRemoved ? null : r;
        }

        .....
        return r;
    }

这里是开始销毁Activity,首先要保存状态,然后标记开始finish,然后调用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 {
                //执行DestroyActivityItem事务,最后会调用DestroyActivityItem的execute方法
                mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,DestroyActivityItem.obtain(r.finishing, r.configChangeFlags));
            } catch (Exception e) {
                ...
            }
 
            ...
 
        return removedFromHistory;
    }
复制代码

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

ActivityStack.cleanUpActivityLocked

    private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) {
        //将指向该销毁的Activity的引用都置空
        onActivityRemovedFromStack(r);

        r.deferRelaunchUntilPaused = false;
        r.frozenBeforeDestroy = false;

        if (setState) {
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
            r.setState(DESTROYED, "cleanupActivityLocked");
            if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
            r.app = null;
        }

        // Inform supervisor the activity has been removed.
        //从列表中移除该Activity对象
        mStackSupervisor.cleanupActivity(r);


        // Remove any pending results.
        if (r.finishing && r.pendingResults != null) {
            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
                PendingIntentRecord rec = apr.get();
                if (rec != null) {
                    mService.cancelIntentSenderLocked(rec, false);
                }
            }
            r.pendingResults = null;
        }
        // 是否清理服务,这里cleanServices=false
        if (cleanServices) {
            cleanUpActivityServicesLocked(r);
        }

        // Get rid of any pending idle timeouts.
        removeTimeoutsForActivityLocked(r);
        // Clean-up activities are no longer relaunching (e.g. app process died). Notify window
        // manager so it can update its bookkeeping.
        mWindowManager.notifyAppRelaunchesCleared(r.appToken);
    }

ApplicationThreadNative.scheduleDestroyActivity

 最终会调用DestoryActivityItem的execute方法

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
        //client为ActivityThread
        client.handleDestroyActivity(token, mFinished, mConfigChanges,
                false /* getNonConfigInstance */, "DestroyActivityItem");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

ActivityThread.handleDestroyActivity

    private void handleDestroyActivity(IBinder token, boolean finishing,
                                       int configChanges, boolean getNonConfigInstance) {
        ActivityClientRecord r = performDestroyActivity(token, finishing,
                configChanges, getNonConfigInstance);
        ...
        if (finishing) {
            try {
                ActivityManager.getService().activityDestroyed(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
        mSomeActivitiesChanged = true;
    }
    ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
            int configChanges, boolean getNonConfigInstance, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        Class<? extends Activity> activityClass = null;
        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
        if (r != null) {
            activityClass = r.activity.getClass();
            r.activity.mConfigChangeFlags |= configChanges;
            if (finishing) {
                r.activity.mFinished = true;
            }
            //r.pause==true,不需要执行pausing过程
            performPauseActivityIfNeeded(r, "destroy");
            //如果还没执行过stop过程,则执行stop过程
            if (!r.stopped) {
                callActivityOnStop(r, false /* saveState */, "destroy");
            }
            ....
            try {
                r.activity.mCalled = false;
                //执行destroy过程,最终调用activity的onDestroy方法
                mInstrumentation.callActivityOnDestroy(r.activity);
                if (!r.activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + safeToComponentShortString(r.intent) +
                        " did not call through to super.onDestroy()");
                }
                if (r.window != null) {
                    r.window.closeAllPanels();
                }
            } catch (SuperNotCalledException e) {
                throw e;
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                            "Unable to destroy activity " + safeToComponentShortString(r.intent)
                            + ": " + e.toString(), e);
                }
            }
            r.setState(ON_DESTROY);
        }
        mActivities.remove(token);
        StrictMode.decrementExpectedActivityCount(activityClass);
        return r;
    }

再回到AMS的activityDestroyed方法中来

    public final void activityDestroyed(IBinder token) {
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
        synchronized (this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityDestroyedLocked(token, "activityDestroyed");
            }
        }
    }

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,前面我们分析过了,不再分析。然后是调用removeActivityFromHistoryLocked方法,就是将该结束的Activity从历史列表中删除.

到这里Activity的finish就分析完了,从这里我们主要学到的是finish的过程,以及finish过程中系统做了哪些处理,我们在写代码过程中应该做那些处理。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值