Activity销毁流程

一 概述

Activity 在以下几种情况下由于正常的应用操作会被销毁,例如:当用户按下后退键或者是 Activity 本身调用了 finish() 方法。此外,如果你的 Activity 生命周期处于 stop 状态而且一段时间内都没有被调用或者是处于前台的 Activity 需要更多的资源而系统资源紧张的时候,系统也会销毁你的 Activity,杀掉后台进程给前台进程留出足够的内存。下面我们来分析 Activity 的销毁流程。

Activity finish到destroy流程

该流程主要描述Activity B 主动finish,然后resume Activity A显示,最后destory Activity B

Activity finish到destroy流程的完整时序图

 

二 onPause阶段

2.1 Activity.finish

frameworks/base/core/java/android/app/Activity.java

public void finish() {
    // finish 当前 Activity,但不 finish 所在的 Task
    finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}

private void finish(int finishTask) {
    if (mParent == null) { // 父 Activity 为空
        int resultCode;
        Intent resultData;
        synchronized (this) {
            resultCode = mResultCode;
            resultData = mResultData;
        }
        if (resultData != null) {
            resultData.prepareToLeaveProcess(this);
        }
        // 调用 ATMS.finishActivity
        if (ActivityTaskManager.getService().finishActivity(
            mToken, resultCode, resultData, finishTask)) {
            mFinished = true;
        }
    } else { // 如果父 Activity 非空,直接 finish 整个 Activity group
        mParent.finishFromChild(this);
    }
    ......
}

以下为是否 finishTask 的几个 flag 参数:

// 当 finish Activity 时,其所在的 Task 不 finish
public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
// 当 finish root Activity 时,其所在的 Task 也 finish, 且 Task 从最近任务列表移除
public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
// 当 finish Activity 时,其所在的 Task 也 finish, 但 Task 不从最近任务列表移除
public static final int FINISH_TASK_WITH_ACTIVITY = 2;

2.2 ActivityTaskManagerService.finishActivity

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

@Override
public final boolean finishActivity(IBinder token, int resultCode,
    Intent resultData, int finishTask) {
    synchronized (mGlobalLock) {
        // 获取当前 ActivityRecord
        ActivityRecord r = ActivityRecord.isInStackLocked(token);
        if (r == null) {
            return true;
        }
        // 获取当前 TaskRecord
        final TaskRecord tr = r.getTaskRecord();
        // 获取当前 ActivityRecord 的根 Activity
        ActivityRecord rootR = tr.getRootActivity();
        ......
        boolean res;
        // 若当前 Activity 为根 Activity,判断是否 finish 根 Activity 所在的 task
        final boolean finishWithRootActivity = 
            finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
        if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY ||
            (finishWithRootActivity && r == rootR)) {
            // finish 当前 task
            res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
                finishWithRootActivity, "finish-activity");
        } else {
            // finish 当前 Activity
            res = tr.getStack().requestFinishActivityLocked(token, resultCode,
                resultData, "app-request", true);
        }
        return res;
    }
}

2.3 ActivityStack.requestFinishActivityLocked

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

final boolean requestFinishActivityLocked(IBinder token,
        int resultCode, Intent resultData, String reason, boolean oomAdj) {
	// 先根据 token 获取 ActivityRecord,然后判断该 ActivityRecord
	// 是否在其所属 Task 的 Activity 列表
    ActivityRecord r = isInStackLocked(token);
    if (r == null) {
        return false;
    }
 
    finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
    return true;
}
2.4 ActivityStack.finishActivityLocked
final boolean finishActivityLocked(ActivityRecord r, int resultCode,
    Intent resultData, String reason, boolean oomAdj) {
    // pauseImmediately 为 false
    return finishActivityLocked(r, resultCode, resultData, reason,
        oomAdj, !PAUSE_IMMEDIATELY);
}


final boolean finishActivityLocked(ActivityRecord r, int resultCode, 
    Intent resultData, String reason, boolean oomAdj, 
    boolean pauseImmediately) {
    mWindowManager.deferSurfaceLayout();   
    try {
        // 设置 Activity 的属性 finishing=true
        r.makeFinishingLocked();
        // 获取当前 task
        final TaskRecord task = r.getTaskRecord();
        // 获取当前 task 中所有 Activity
        final ArrayList<ActivityRecord> activities = task.mActivities;
        // 获取当前 Activity 的索引
        final int index = activities.indexOf(r);
        if (index < (activities.size() - 1)) {// 如果当前不是最后一个 Activity
            task.setFrontOfTask();
            if ((r.intent.getFlags() &
                Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
         // 如果当前 Activity 的 flags 为 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
            // 则将该 flags 传递给下一个Activity
            ActivityRecord next = activities.get(index+1);
            next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
            }
        }
 
        // 暂停 Key 分发事件
        r.pauseKeyDispatchingLocked();
        // 将当前 Activity 及其所在 Task 调整到最前面,使其 focused
        adjustFocusedActivityStack(r, "finishActivity");
 
        // 创建 ActivityResult, 并将其添加到启动当前 Activity
        // 的那个 Activity 的 ActivityResult 列表 results
        finishActivityResultsLocked(r, resultCode, resultData);
 
        // 判断是否清除当前 task: 当前 Activity 位于栈底
        // 且 Task 不复用时,则结束 Task
        final boolean endTask = index <= 0 &&
            !task.isClearingToReuseTask();
        // 设置转换模式
        final int transit = endTask ? TRANSIT_TASK_CLOSE :
            TRANSIT_ACTIVITY_CLOSE;
        if (mResumedActivity == r) { // 当前 Activity 为 Resumed 状态
            if (endTask) {
                // 通知 listeners 当前 Task 即将被移除
                mService.getTaskChangeNotificationController().
                    notifyTaskRemovalStarted(task.getTaskInfo());
            }
            getDisplay().mDisplayContent.prepareAppTransition(transit, false);
 
            // 设置 Activity 不可见,告诉 WindowManager 当前 Activity 即将被移除
            r.setVisibility(false);
 
            if (mPausingActivity == null) {
                // 执行 pause 操作.
                startPausingLocked(false, false, null, pauseImmediately);
            }
 
            if (endTask) {
                // 清除当前 Task
                mService.getLockTaskController().clearLockedTask(task);
            }
        } else if (!r.isState(PAUSING)) { // 当前 Activity 非 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 (r.visible) {
                // 设置 Activity 为不可见
                prepareActivityHideTransitionAnimation(r, transit);
            }
 
            // 设置 finishMode
            final int finishMode = (r.visible || r.nowVisible) ?
                FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE;
            // finish 当前 Activity
            final boolean removedActivity = 
            finishCurrentActivityLocked(r, finishMode, oomAdj,
                "finishActivityLocked") == null; 
           
            if (task.onlyHasTaskOverlayActivities(true)) {
                for (ActivityRecord taskOverlay : task.mActivities) {
                    if (!taskOverlay.mTaskOverlay) {
                        continue;
                    }
                    prepareActivityHideTransitionAnimation(
                        taskOverlay, transit);
                }
            }
            return removedActivity;
        }
 
        return false;
    } finally {
        mWindowManager.continueSurfaceLayout();
    }
}
2.4.1 ActivityStack.finishActivityResultsLocked
private void finishActivityResultsLocked(ActivityRecord r,
    int resultCode, Intent resultData) {
    // resultTo 为 startActivity 时启动当前 Activity 的那个
    // Activity (当前 Activity 的结果发给这个 Activity)
    ActivityRecord resultTo = r.resultTo;
    if (resultTo != null) {
        if (resultTo.mUserId != r.mUserId) {
            if (resultData != null) {
                resultData.prepareToLeaveUser(r.mUserId);
            }
        }
        if (r.info.applicationInfo.uid > 0) {
            // 授予 Uri 权限
            mService.mUgmInternal.grantUriPermissionFromIntent(
                    r.info.applicationInfo.uid,
                    resultTo.packageName, resultData,
                    resultTo.getUriPermissionsLocked(), resultTo.mUserId);
        }
        // 创建 ActivityResult, 并添加到 resultTo 的 ActivityResult 列表 results 
        resultTo.addResultLocked(r, r.resultWho,
                r.requestCode, resultCode, resultData);
        r.resultTo = null;
    }
 
    // 当前 Activity 属性置空
    r.results = null;
    r.pendingResults = null;
    r.newIntents = null;
    r.icicle = null;
}
2.4.2 ActivityRecord.addResultLocked

frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java

void addResultLocked(ActivityRecord from, String resultWho,
        int requestCode, int resultCode, Intent resultData) {
    ActivityResult r = new ActivityResult(from, resultWho,
            requestCode, resultCode, resultData);
    if (results == null) {
        results = new ArrayList<ResultInfo>();
    }
    results.add(r);
}
2.5 ActivityStack.startPausingLocked
// 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.
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
    ActivityRecord resuming, boolean pauseImmediately) {
    // 如果当前有 pausing 状态的 Activity(即 mPausingActivity 非空),
    // 则完成 Pause 过程
    if (mPausingActivity != null) {
        if (!shouldSleepActivities()) {
            completePauseLocked(false, resuming);
        }
    }
    ActivityRecord prev = mResumedActivity;
 
    // Trying to pause when nothing is resumed
    // 我理解这段代码含义: 当前没有 resume 状态的 Activity, 说明这是一个 resume 过程
    // 因此 resume top activity, 然后直接 return false. 正常的 Pause 走不到这里
    if (prev == null && resuming == null) {
        mRootActivityContainer.resumeFocusedStacksTopActivities();
        return false;
    }
 
    // Trying to pause activity that is in process of being resumed
    if (prev == resuming) {
        return false;
    }
 
    // 将之前 Resumed Activity 设置为当前 Paused Activity
    mPausingActivity = prev;
    mLastPausedActivity = prev;
    mLastNoHistoryActivity = (prev.intent.getFlags() &
         Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
         || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ?
          prev : null;
    // 设置 Activity 状态为 Pausing
    prev.setState(PAUSING, "startPausingLocked");
    ......
 
    if (prev.attachedToProcess()) { // 进程非空
        // 执行 PauseActivityItem 事务
        mService.getLifecycleManager().scheduleTransaction(
            prev.app.getThread(), prev.appToken,
            PauseActivityItem.obtain(prev.finishing, userLeaving,
                        prev.configChangeFlags, pauseImmediately));
    } 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) {
        if (!uiSleeping) {
            prev.pauseKeyDispatchingLocked();
        }
 
        if (pauseImmediately) { // 立即 pause
            completePauseLocked(false, resuming);
            return false;
        } else { // 500ms延时再pause
            schedulePauseTimeout(prev);
            return true;
        }
    } else { // Pause 失败
        // This activity failed to schedule the pause, 
        // so just treat it as being paused now.
        if (resuming == null) {
            mRootActivityContainer.resumeFocusedStacksTopActivities();
        }
        return false;
    }
}

2.6 PauseActivityItem

frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java

public class PauseActivityItem extends ActivityLifecycleItem {
    @Override
    public void execute(ClientTransactionHandler client,
            IBinder token, PendingTransactionActions pendingActions) {
        client.handlePauseActivity(token, mFinished,
        mUserLeaving, mConfigChanges, pendingActions, "PAUSE_ACTIVITY_ITEM");
    }

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

    @Override
    public void postExecute(ClientTransactionHandler client,
            IBinder token, PendingTransactionActions pendingActions) {
        ActivityTaskManager.getService().activityPaused(token);
    }
}

回调通知 client 进程,调用 Activity 的 onPause 方法,client 执行完成后,就会调用通知 ATMS,这个流程我们之前在分析 Activity 的启动流程中已经详细分析过了 Activity启动流程3.2 中。继续进入 ATMS 的 activityPaused 方法:

2.7 ActivityTaskManagerService.activityPaused

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

@Override
public final void activityPaused(IBinder token) {
    synchronized (mGlobalLock) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
}

2.8 ActivityStack.activityPausedLocked

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

final void activityPausedLocked(IBinder token, boolean timeout) {
    final ActivityRecord r = isInStackLocked(token);
 
    if (r != null) {
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) { // 继续完成 pause 操作
            completePauseLocked(true, null);
            return;
        } else {
            if (r.isState(PAUSING)) { // pause 失败的 Activity,直接 finish 掉
                r.setState(PAUSED, "activityPausedLocked");
                if (r.finishing) {
                    finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE,
                    false, "activityPausedLocked");
                }
            }
        }
    }
    mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}

2.9 ActivityStack.completePauseLocked

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    ActivityRecord prev = mPausingActivity;

    if (prev != null) {
        prev.setWillCloseOrEnterPip(false);
        // wasStopping 为 false
        final boolean wasStopping = prev.isState(STOPPING);
        // 设置 Activity 状态为 PAUSED
        prev.setState(PAUSED, "completePausedLocked");
        if (prev.finishing) { // 会走到这里
            // 关键点1 finish Activity
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE,
                false, "completePausedLocked");
        } else if (prev.hasProcess()) {
            if (prev.deferRelaunchUntilPaused) {
                prev.relaunchActivityLocked(false /* andResume */,
                    prev.preserveWindowOnDeferredRelaunch);
            } else if (wasStopping) {
                prev.setState(STOPPING, "completePausedLocked");
            } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
                // Clear out any deferred client hide we might currently have.
                prev.setDeferHidingClient(false);
                // If we were visible then resumeTopActivities will 
                // release resources before stopping.
                addToStopping(prev, true /* scheduleIdle */,
                    false /* idleDelayed */, "completePauseLocked");
            }
        } else { // App died during pause, not stopping
            prev = null;
        }        
        if (prev != null) {
            prev.stopFreezingScreenLocked(true /*force*/);
        }
        mPausingActivity = null;
    }
 
    if (resumeNext) { // 是否恢复下一个 Activity
        final ActivityStack topStack = 
            mRootActivityContainer.getTopDisplayFocusedStack();
        if (!topStack.shouldSleepOrShutDownActivities()) {
            // 关键点2:如果没有休眠和关机时,恢复顶层 Activity
            // 也就是 resume 下个页面
            mRootActivityContainer.resumeFocusedStacksTopActivities(
                topStack, prev, null);
        } else {
            // 等待休眠完成,再恢复顶层 Activity
            checkReadyForSleep();
            ActivityRecord top = topStack.topRunningActivityLocked();
            if (top == null || (prev != null && top != prev)) {
                mRootActivityContainer.resumeFocusedStacksTopActivities();
            }
        }
    } 
    ...... 
    mRootActivityContainer.ensureActivitiesVisible(
        resuming, 0, !PRESERVE_WINDOWS);
}

此时第一步,会调用自身的 finishCurrentActivityLocked 方法,第二步调用 RootActivityContainer 的 resumeFocusedStacksTopActivities。下面先看第一步的调用流程:

三 下一个页面的onResume阶段

3.1 ActivityStack.finishCurrentActivityLocked

final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
    int mode, boolean oomAdj, String reason) {
    final ActivityDisplay display = getDisplay();
    // 获取下一个 Activity
    final ActivityRecord next = 
    display.topRunningActivity(true);
    final boolean isFloating = 
    r.getConfiguration().windowConfiguration.tasksAreFloating();
 
	// 如果 mode 为 FINISH_AFTER_VISIBLE 且下一个 Activity 不可见(默认即为此),
	// 则先将当前 Activity 添加到 stopping 列表,并将其状态设置为 STOPPING
	// 等下一个 Activity 可见后再 finish 当前 Activity
    if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
            && next != null && !next.nowVisible && !isFloating) {
        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
            // 添加到 stopping 列表.
            addToStopping(r, false /* scheduleIdle */,
                false /* idleDelayed */, "finishCurrentActivityLocked");
        }
 
        // Activity 状态设置为 STOPPING
        r.setState(STOPPING, "finishCurrentActivityLocked");
        if (oomAdj) {
            mService.updateOomAdj();
        }
        return r;
    }
 
    // make sure the record is cleaned out of other places.
    mStackSupervisor.mStoppingActivities.remove(r);
    mStackSupervisor.mGoingToSleepActivities.remove(r);
 
    // 获取当前状态
    final ActivityState prevState = r.getState();
 
    // Activity 状态设置为 FINISHING
    r.setState(FINISHING, "finishCurrentActivityLocked");
    // 如果没有要显示的下一个 Activity 且当前显示的栈中包含 Home 栈,
    // 则先等 HomeActivity 恢复之后
    // 再销毁当前 Activity 这样做的目的是避免出现临时黑屏
    final boolean noRunningStack = next == null &&
    display.topRunningActivity() == null &&
    display.getHomeStack() == null;
    
    final boolean noFocusedStack = r.getActivityStack() != 
         display.getFocusedStack();
    final boolean finishingInNonFocusedStackOrNoRunning = mode == 
        FINISH_AFTER_VISIBLE &&
        prevState == PAUSED && (noFocusedStack || noRunningStack);
 
    if (mode == FINISH_IMMEDIATELY
            || (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE ||
                 inPinnedWindowingMode()))
            || finishingInNonFocusedStackOrNoRunning
            || prevState == STOPPING
            || prevState == STOPPED
            || prevState == ActivityState.INITIALIZING) {
        // 设置 finishing=true
        r.makeFinishingLocked();
        // 销毁当前 Activity
        boolean activityRemoved = destroyActivityLocked(
            r, true, "finish-imm:" + reason);
 
        if (finishingInNonFocusedStackOrNoRunning) {
            mRootActivityContainer.ensureVisibilityAndConfig(
                next, mDisplayId,
            false /* markFrozenIfConfigChanged */, true);
        }
        if (activityRemoved) {
            mRootActivityContainer.resumeFocusedStacksTopActivities();
        }
        return activityRemoved ? null : r;
    }
    if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
    mStackSupervisor.mFinishingActivities.add(r);
    r.resumeKeyDispatchingLocked();
    mRootActivityContainer.resumeFocusedStacksTopActivities();
    if (r.isState(RESUMED) && mPausingActivity != null) {
        startPausingLocked(false /* userLeaving */, false,
        next /* resuming */, false /* dontWait */);
    }
    return r;
}

以下为 finishMode:

// 立刻 finish 当前 Activity
static final int FINISH_IMMEDIATELY = 0;
// 当前 Activity pause 后 finish
static final int FINISH_AFTER_PAUSE = 1;
// 下一个要显示的 Activity 可见后再 finish 当前 Activity
static final int FINISH_AFTER_VISIBLE = 2;

此时会进入第一个 if 判断中,执行 addToStopping 方法,并不会调用下面的 destroyActivityLocked 的方法。

3.2 ActivityStack.addToStopping

private void addToStopping(ActivityRecord r, boolean scheduleIdle,
    boolean idleDelayed, String reason) {
    if (!mStackSupervisor.mStoppingActivities.contains(r)) {
        // 将当前 Activity 添加到 stopping 列表
        mStackSupervisor.mStoppingActivities.add(r);
    }
    // 如果 stopping 列表超出最大值,或者当前 Activity 为所在 Task 的根 Activity
    // 且任务历史列表只剩这一个 Task 则先保持 idle,暂时不做什么
    boolean forceIdle = mStackSupervisor.mStoppingActivities.size() >
            MAX_STOPPING_TO_FORCE
            || (r.frontOfTask && mTaskHistory.size() <= 1);
    if (scheduleIdle || forceIdle) {
        if (!idleDelayed) {
            mStackSupervisor.scheduleIdleLocked();
        } else {
            mStackSupervisor.scheduleIdleTimeoutLocked(r);
        }
    } else { // sleep
        checkReadyForSleep();
    }
}

addToStopping 的第一步操作就是把此将要 finish 的 Activity 加入到 stopping 列表,第二步是发送一个超时消息,如果 10S 后,此消息没有被移除,就会触发执行。

3.2.1 ActivityStackSupervisor.scheduleIdleLocked
final void scheduleIdleLocked() {
    mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
3.2.2 ActivityStackSupervisorHandler
private final class ActivityStackSupervisorHandler extends Handler {

    public ActivityStackSupervisorHandler(Looper looper) {
        super(looper);
    }

    void activityIdleInternal(ActivityRecord r,
        boolean processPausingActivities) {
        synchronized (mService.mGlobalLock) {
            activityIdleInternalLocked(r != null ? r.appToken : null, true,
                    processPausingActivities, null);
        }
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            ......
            case IDLE_TIMEOUT_MSG: {
                activityIdleInternal((ActivityRecord) msg.obj,
                        true /* processPausingActivities */);
            } break;
            case IDLE_NOW_MSG: {
                activityIdleInternal((ActivityRecord) msg.obj,
                        false /* processPausingActivities */);
            } break;
            ......
        }
    }
3.2.3 activityIdleInternalLocked

启动 Activity 时会先去暂停当前显示的 Activity,当待启动 Activity 启动完成时回调 AMS 的 activityIdleInternalLocked() 函数。在该函数中会执行内存回收操作。

activityIdleInternalLocked() 函数内部依次处理 stop、finish 状态的 Activity,最后会执行到 AMS 的 trimApplications(),在该函数中执行内存回收。

activityIdleInternalLocked() 是执行内存回收的关键函数。

activityIdleInternalLocked() 被调用的时机:

  • 首先是 Activity 启动成功时 ActivityThread 会回调 AMS 的相关方法最后执行到 activityIdleInternalLocked()
  • 在 WMS 回调 ActivityRecord 其 window 可见时,会回调 activityIdleInternalLocked()
  • 在 completePauseLocked() 中当 stop 状态 Activity 数目大于3时会回调 activityIdleInternalLocked(),这种情况一般不出现
  • 最后是在 completePauseLocked() 启动 10s 定时,如果 ActivityThread 启动 Activity 未成功,10s 时间到达会回调 activityIdleInternalLocked()

顺便多说明以下,执行 AMS.trimApplications() 的过程:

下面再来看下 ActivityStack.completePauseLocked 方法中,第二步调用 RootActivityContainer 的 resumeFocusedStacksTopActivities 方法流程,目的是在 finish 此 Activity 之前,先去把下一个要显示的 Activity 设置为 resume 状态

3.3 RootActivityContainer.resumeFocusedStacksTopActivities

boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, 
    ActivityRecord target, ActivityOptions targetOptions) {
	if (!mStackSupervisor.readyToResume()) {
		return false;
	}

	boolean result = false;
	if (targetStack != null && (targetStack.isTopStackOnDisplay()
			|| getTopDisplayFocusedStack() == targetStack)) {
		result = targetStack.resumeTopActivityUncheckedLocked(
		    target, targetOptions);
	}
	......
	return result;
}

 根据之前分析的 Activity 的启动流程,我们知道这个方法最终会调用到 ActivityStack 的 resumeTopActivityInnerLocked。我们直接来看这个方法。

3.4 ActivityStack.resumeTopActivityInnerLocked

private boolean resumeTopActivityInnerLocked(ActivityRecord prev,
        ActivityOptions options) {
    ......
    // 从任务历史列表 mTaskHistory 里, 获取最上面运行的 Activity
    ActivityRecord next = topRunningActivityLocked(true);
    final boolean hasRunningActivity = next != null;
    if (!hasRunningActivity) {
        // 如果没有运行的 Activity, 则从其他 task 堆栈中查找 Activity 并 resume
        return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
    }
    // 如果 topRunningActivity 已经是 resume 状态, 则 do nothing
    if (mResumedActivity == next && next.isState(RESUMED) &&
            display.allResumedActivitiesComplete()) {
        executeAppTransition(options);
        return false;
    }
    ......
    // 如果没有获取到 topRunningActivity,则先暂停所有 Stack 中的 Activity.
    // 前面就是在这个方法中判断需要先 pause 当前 Activity 的
    boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
    // 暂停当前恢复态的 Activity(mResumedActivity),注意 prev/next 为要启动的
    // 目的 Activity, 而 mResumedActivity 为当前 Activity, 两者不是同一个
    if (mResumedActivity != null) {
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    if (pausing && !resumeWhilePausing) {
        // 如果 Activity 正在 Pausing 状态,且不允许 pausing 过程中执行 resume, 
        // 则先不执行 resume 只是将即将启动的 Activity 所在的进程添加到
        // mLruProcesses 最前面, 避免被杀
        if (next.attachedToProcess()) {
            next.app.updateProcessInfo(false, true, false);
        }
        if (lastResumed != null) {
            lastResumed.setWillCloseOrEnterPip(true);
        }
        return true;
    } else if (mResumedActivity == next && next.isState(RESUMED) &&
                display.allResumedActivitiesComplete()) {
        // 如果要启动的 Activity 已经 Resume 了则不需要做什么
        // 调一下 executeAppTransition 执行一下 pending transitions 即可.
        executeAppTransition(options);
        return true;
    }
    ......
    // 如果下一个 Activity 已经可见了, 上一个 Activity 当前正处于 finishing 状态
    // 则直接让上一个 Activity 不可见,当上一个 Activity 不是 finishing 状态
    //(比如当下一个 Activity 不是全屏状态时的场景), 上一个 Activity 还应该是可见的
    if (prev != null && prev != next && next.nowVisible) {
        if (prev.finishing) {
            prev.setVisibility(false);
        }
    }
    ......
    if (next.attachedToProcess()) {// 会走这个分支
        // Activity 所在进程已启动, 和 realStartActivityLocked 做的事情类似.
        // 上一个 Activity 是否半透明
        final boolean lastActivityTranslucent = lastFocusedStack != null
                && (lastFocusedStack.inMultiWindowMode()
                || (lastFocusedStack.mLastPausedActivity != null
                && !lastFocusedStack.mLastPausedActivity.fullscreen)); 
        // 如果将要启动的 Activity 不可见, 则让该 Activity 可见
        if (!next.visible || next.stopped || lastActivityTranslucent) {
            next.setVisibility(true);
        }
        ......
        // 设置 Activity 状态为 RESUMED
        next.setState(RESUMED, "resumeTopActivityInnerLocked");
        // 更新进程信息
        next.app.updateProcessInfo(false, true, true);
        ......
        // 关键点1:生成 ClientTransaction
        final ClientTransaction transaction = 
            ClientTransaction.obtain(next.app.getThread(), next.appToken);
        // 分发所有 pending 结果
        ArrayList<ResultInfo> a = next.results;
        if (a != null) {
            final int N = a.size();
            if (!next.finishing && N > 0) {
                transaction.addCallback(ActivityResultItem.obtain(a));
            }
        } 
        // 分发 new intent
        if (next.newIntents != null) {
            transaction.addCallback(
                NewIntentItem.obtain(next.newIntents, true));
        } 
        // Well the app will no longer be stopped.
        // Clear app token stopped state in window manager if needed.
        next.notifyAppResumed(next.stopped);
        next.sleeping = false;
        mService.getAppWarningsLocked().onResumeActivity(next);
next.app.setPendingUiCleanAndForceProcessStateUpTo(mService.mTopProcessState);
        next.clearOptionsLocked();
        // 关键点2:触发 onResume
       transaction.setLifecycleStateRequest(
		       ResumeActivityItem.obtain(next.app.getReportedProcState(), 
		       getDisplay().mDisplayContent.isNextTransitionForward()));
        mService.getLifecycleManager().scheduleTransaction(transaction); 
        // From this point on, if something goes wrong there is no way
        // to recover the activity.
        next.completeResumeLocked();
    } else {// 进程没启动,不会走这里
        ......
    }
    return true;
}

和 Activity 启动过程类似,最终会将要显示的 Activity 置为 resume 状态。这里需要关注的是 ActivityThread 的 handleResumeActivity 方法。我们来看这个方法的最后一句代码:

3.5 ActivityThread.handleResumeActivity

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

可以看到,在 handleResumeActivity 方法的最后一句,生成了一个 Idler 对象,并添加到了消息队列中,熟悉消息机制的同学们应该知道,在没有消息执行的情况下,就会执行这个 Idler 对象的 queueIdle 回调方法。不熟悉的可以参考 Android消息机制1 (Java层)。

也就是说:上一个将要显示的 Activity 被 resume 后,会进入 idle 状态,即调用到了 client 的 Idler.queueIdle 方法中,此方法内部接着调用了 ATMS 的 activityIdle 方法,目的是把之前加入到 stopping 列表中的将要 finish 的 Activity,去进行真正的销毁操作。

四 onStop和onDestroy阶段

4.1 Idler.queueIdle

ActivityThread.java

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

4.2 ATMS.activityIdle

@Override
    public final void activityIdle(IBinder token, Configuration config,
            boolean stopProfiling) {
        final long origId = Binder.clearCallingIdentity();
        try {
            WindowProcessController proc = null;
            synchronized (mGlobalLock) {
                ActivityStack stack = ActivityRecord.getStackLocked(token);
                if (stack == null) {
                    return;
                }
                // 关键调用
                final ActivityRecord r =
                mStackSupervisor.activityIdleInternalLocked(token,
                        false, false, config);
                if (r != null) {
                    proc = r.app;
                }
                if (stopProfiling && proc != null) {
                    proc.clearProfilerIfNeeded();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

4.3 ActivityStackSupervisor.activityIdleInternalLocked

final ActivityRecord activityIdleInternalLocked(final IBinder token, 
    boolean fromTimeout, boolean processPausingActivities,
    Configuration config) {
        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);

        ArrayList<ActivityRecord> finishes = null;
        ArrayList<UserState> startingUsers = null;
        int NS = 0;
        int NF = 0;
        boolean booting = false;
        boolean activityRemoved = false;

        ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (r != null) {
            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
            r.finishLaunchTickingLocked();
            if (fromTimeout) {
                reportActivityLaunchedLocked(fromTimeout, r, INVALID_DELAY,
                        -1 /* launchState */);
            }           
            if (config != null) {
                r.setLastReportedGlobalConfiguration(config);
            }
            r.idle = true;

            if ((mService.isBooting() &&
             mRootActivityContainer.allResumedActivitiesIdle())
                    || fromTimeout) {
                booting = checkFinishBootingLocked();
            }           
            r.mRelaunchReason = RELAUNCH_REASON_NONE;
        }

        if (mRootActivityContainer.allResumedActivitiesIdle()) {
            if (r != null) {
                mService.scheduleAppGcsLocked();
            }

            if (mLaunchingActivityWakeLock.isHeld()) {
                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
                if (VALIDATE_WAKE_LOCK_CALLER &&
                        Binder.getCallingUid() != Process.myUid()) {
                    throw new IllegalStateException(
                    "Calling must be system uid");
                }
                mLaunchingActivityWakeLock.release();
            }
            mRootActivityContainer.ensureActivitiesVisible(
            null, 0, !PRESERVE_WINDOWS);
        }

        // Atomically retrieve all of the other things to do.
        // 关键点:处理之前处于 stopping 状态的 Activity
        final ArrayList<ActivityRecord> stops = 
        processStoppingActivitiesLocked(r,
                true /* remove */, processPausingActivities);
        NS = stops != null ? stops.size() : 0;
        if ((NF = mFinishingActivities.size()) > 0) {
            finishes = new ArrayList<>(mFinishingActivities);
            mFinishingActivities.clear();
        }

        if (mStartingUsers.size() > 0) {
            startingUsers = new ArrayList<>(mStartingUsers);
            mStartingUsers.clear();
        }

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

        // Finish any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NF; i++) {
            r = finishes.get(i);
            final ActivityStack stack = r.getActivityStack();
            if (stack != null) {
                activityRemoved |= stack.destroyActivityLocked(
                r, true, "finish-idle");
            }
        }
        ......
        mService.mH.post(() -> mService.mAmInternal.trimApplications());
        //dump();
        //mWindowManager.dump();
        if (activityRemoved) {
            mRootActivityContainer.resumeFocusedStacksTopActivities();
        }

        return r;
    }

 

activityIdleInternalLocked() 函数内部依次处理 stop、finish 状态的 Activity,最后会执行到 AMS 的 trimApplications(),在该函数中执行内存回收。在这个方法中的关键就是对 stopping 状态的 Activity 的处理。

4.4 ActivityStack.finishCurrentActivityLocked

final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
    int mode, boolean oomAdj, String reason) {
    final ActivityDisplay display = getDisplay();
    // 获取下一个 Activity
    final ActivityRecord next = 
    display.topRunningActivity(true);
    final boolean isFloating = 
    r.getConfiguration().windowConfiguration.tasksAreFloating();
 
	// 如果 mode 为 FINISH_AFTER_VISIBLE 且下一个 Activity 不可见(默认即为此),
	// 则先将当前 Activity 添加到 stopping 列表,并将其状态设置为 STOPPING
	// 等下一个 Activity 可见后再 finish 当前 Activity
    if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
            && next != null && !next.nowVisible && !isFloating) {
        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
            // 添加到 stopping 列表.
            addToStopping(r, false /* scheduleIdle */,
                false /* idleDelayed */, "finishCurrentActivityLocked");
        }
 
        // Activity 状态设置为 STOPPING
        r.setState(STOPPING, "finishCurrentActivityLocked");
        if (oomAdj) {
            mService.updateOomAdj();
        }
        return r;
    }
 
    // make sure the record is cleaned out of other places.
    mStackSupervisor.mStoppingActivities.remove(r);
    mStackSupervisor.mGoingToSleepActivities.remove(r);
 
    // 获取当前状态
    final ActivityState prevState = r.getState();
 
    // Activity 状态设置为 FINISHING
    r.setState(FINISHING, "finishCurrentActivityLocked");
    // 如果没有要显示的下一个 Activity 且当前显示的栈中包含 Home 栈,
    // 则先等 HomeActivity 恢复之后
    // 再销毁当前 Activity 这样做的目的是避免出现临时黑屏
    final boolean noRunningStack = next == null &&
    display.topRunningActivity() == null &&
    display.getHomeStack() == null;
    
    final boolean noFocusedStack = r.getActivityStack() != 
         display.getFocusedStack();
    final boolean finishingInNonFocusedStackOrNoRunning = mode == 
        FINISH_AFTER_VISIBLE &&
        prevState == PAUSED && (noFocusedStack || noRunningStack);
 
    if (mode == FINISH_IMMEDIATELY
            || (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE ||
                 inPinnedWindowingMode()))
            || finishingInNonFocusedStackOrNoRunning
            || prevState == STOPPING
            || prevState == STOPPED
            || prevState == ActivityState.INITIALIZING) {
        // 设置 finishing=true
        r.makeFinishingLocked();
        // 关键点:销毁当前 Activity
        boolean activityRemoved = destroyActivityLocked(
            r, true, "finish-imm:" + reason);
 
        if (finishingInNonFocusedStackOrNoRunning) {
            mRootActivityContainer.ensureVisibilityAndConfig(
                next, mDisplayId,
            false /* markFrozenIfConfigChanged */, true);
        }
        if (activityRemoved) {
            mRootActivityContainer.resumeFocusedStacksTopActivities();
        }
        return activityRemoved ? null : r;
    }
    if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
    mStackSupervisor.mFinishingActivities.add(r);
    r.resumeKeyDispatchingLocked();
    mRootActivityContainer.resumeFocusedStacksTopActivities();
    if (r.isState(RESUMED) && mPausingActivity != null) {
        startPausingLocked(false /* userLeaving */, false,
        next /* resuming */, false /* dontWait */);
    }
    return r;
}

这里不会想之前执行 addToStopping 方法了,而是执行 destroyActivityLocked 操作.

4.5 ActivityStack.destroyActivityLocked

final boolean destroyActivityLocked(ActivityRecord r,
        boolean removeFromApp, String reason) {
    if (r.isState(DESTROYING, DESTROYED)) {
        return false;
    }

    boolean removedFromHistory = false;
 
    cleanUpActivityLocked(r, false, false);
 
    final boolean hadApp = r.hasProcess();
 
    if (hadApp) {
        if (removeFromApp) {
            r.app.removeActivity(r);
            if (!r.app.hasActivities()) {
                mService.clearHeavyWeightProcessIfEquals(r.app);
            }
            if (!r.app.hasActivities()) {
                r.app.updateProcessInfo(true,
                        false, true /* updateOomAdj */);
            }
        }
 
        boolean skipDestroy = false;
 
        // 关键调用:将最终状态设置为 DestroyActivityItem
        mService.getLifecycleManager().scheduleTransaction(
            r.app.getThread(), r.appToken,
            DestroyActivityItem.obtain(r.finishing, r.configChangeFlags));
         
        r.nowVisible = false;
        if (r.finishing && !skipDestroy) {
            // Activity 状态设置为 DESTROYING
            r.setState(DESTROYING, 
                "destroyActivityLocked. finishing and not skipping destroy");
            Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
            mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
        } else {
            r.setState(DESTROYED, 
                "destroyActivityLocked. not finishing or skipping destroy");
            r.app = null;
        }
    } else {
        // remove this record from the history.
        if (r.finishing) {
            removeActivityFromHistoryLocked(r, reason + " hadNoApp");
            removedFromHistory = true;
        } else {
            r.setState(DESTROYED, 
                "destroyActivityLocked. not finishing and had no app");
            r.app = null;
        }
    }
 
    r.configChangeFlags = 0;
 
    return removedFromHistory;
}

可以看到,最终是通过执行 DestroyActivityItem 来完成 onStop 和 onDestroy 生命周期的调用的,至于为什么会执行 onStop 生命周期,请同学们参考 深入理解 ClientLifecycleManager 机制 中对 cycleToPath 的分析。至于详细的 onStop 和 onDestroy 的调用,之前已经有介绍,在此不再赘述。

 

  • 14
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: activity是Android中的一个组件,用于构建用户界面和处理用户交互。其工作流程如下: 1. 创建activity:当用户启动应用程序或从其他activity转换到当前activity时,系统会创建一个新的activity实例。 2. 加载布局:activity创建后,系统会加载与之关联的布局文件,并将其显示在屏幕上。 3. 处理用户交互:用户与activity交互时,系统会调用相应的回调方法,例如onCreate、onStart、onResume等。 4. 处理生命周期:当用户离开当前activity或者屏幕被覆盖时,系统会调用相应的回调方法,例如onPause、onStop、onDestroy等。 5. 保存和恢复状态:当activity销毁并重新创建时,系统会保存和恢复其状态,以确保用户体验的连续性。 总之,activity是Android应用程序中最重要的组件之一,负责处理用户界面和用户交互,同时也需要处理生命周期和状态保存等问题。 ### 回答2: activity工作流程是指在软件开发过程中,将一个复杂的业务流程拆分成一系列的简单的活动或任务,并通过定义这些活动之间的逻辑关系,实现任务的协作和执行。 首先,需要明确定义业务流程的目标和要求。然后,通过业务分析,将业务流程拆分成各个子任务或活动,并确定它们的执行顺序和依赖关系。 接下来,需要对每个活动进行详细设计和实现。这包括确定活动的输入和输出,定义活动所需的资源和工具,以及编写执行该活动的代码。 在实际执行过程中,根据活动之间的关系,可以采用串行、并行或条件分支的方式来组织活动的执行顺序。每个活动在执行时,需要根据预设条件进行判断,确定是否满足执行条件。如果满足条件,则执行该活动;如果不满足条件,则等待条件满足后再执行。 在活动执行过程中,还需要及时记录活动的执行结果和状态,并根据需要进行相应的处理。如果某个活动执行失败,可以根据事先定义的异常处理策略,进行异常处理,并进行相应的后续操作。 最后,根据整个业务流程的执行结果,进行相应的汇总和统计,并输出相应的报告或结果。 总结来说,activity工作流程是通过将复杂的业务流程拆分成若干个简单的活动,并通过定义它们之间的逻辑关系和执行顺序,实现业务流程的自动化执行和协作。它可以提高工作效率,减少人为操作的错误,并方便对业务流程进行管理和监控。 ### 回答3: Activity工作流程是一种流行的、灵活的工作流程管理框架。它适用于各种类型的应用程序,包括企业、电子商务和科学应用。下面是Activity工作流程的详细解释。 Activity工作流程由一系列活动(Activity)组成,这些活动表示可以在应用程序中执行的任务或操作。每个活动都有一个特定的目标,并且通常是按照特定的顺序进行的。 工作流程开始于一个起始活动(Start Activity),表示工作流程的起点。然后,根据定义的规则和条件,系统将根据不同的条件选择执行不同的活动。 在Activity工作流程中,活动可以是串行的(Sequential),也可以是并行的(Parallel)。串行活动按顺序执行,而并行活动可以同时执行。这使得Activity工作流程非常灵活,可以适应各种业务场景的需求。 每个活动都可以定义输入和输出数据,以及执行的规则和条件。这些规则和条件可用于控制工作流程的流转,并在需要时触发特定的行为或决策。 在Activity工作流程中,活动之间可以有依赖关系,也可以有分支和合并。这些依赖关系和控制结构可以用来管理工作流程的执行顺序和条件。例如,如果某个活动的执行条件不满足,工作流程可以跳过该活动并继续执行其他活动。 工作流程的最后一个活动通常是结束活动(End Activity),表示工作流程的终点。当活动执行到结束活动时,工作流程就完成了。 总的来说,Activity工作流程是一种灵活而强大的工作流程管理框架,可以在各种场景中使用。它的特点包括定义明确的活动、支持串行和并行执行、具有条件和规则控制等。通过使用Activity工作流程,可以更加有效地管理和执行复杂的业务流程

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值