Activity退出流程(基于AOSP 13)

Activity退出流程

1、onPause

1.1 服务侧发起Pause

Activity启动流程中,我们知道会调用startPausing方法来触发栈顶的activity进入onPause状态。

// frameworks\base\services\core\java\com\android\server\wm\TaskFragment.java

boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
        String reason) {
    ...
    if (prev.attachedToProcess()) {
        .....
        // 调用pause周期
        schedulePauseActivity(prev, userLeaving, pauseImmediately, reason);
    }
    if (mPausingActivity != null) {
       // 启动定时
        prev.schedulePauseTimeout();
        // 未设置的准备,因为我们现在需要等到完成此暂停。
        mTransitionController.setReady(this, false /* ready */);
        return true;
    }
}

schedulePauseActivity 方法主要发送对应的ActivityLifecycleItem,即PauseActivityItem给到客户端。

void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
        boolean pauseImmediately, String reason) {
   try {
        // 发送Pause的事务
        mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
                        prev.configChangeFlags, pauseImmediately));
    } catch (Exception e) {
       ....
    }
}

1.2 应用侧执行Pause

通过Activity生命周期流程中分析,知道最终会调用事务的execute

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

 @Override
 public void execute(ClientTransactionHandler client, IBinder token,
         PendingTransactionActions pendingActions) {
     // 调用ActivityThread的handlePauseActivity
     client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
             "PAUSE_ACTIVITY_ITEM");
 }

 @Override
 public void postExecute(ClientTransactionHandler client, IBinder token,
         PendingTransactionActions pendingActions) {
     // 将当前的周期状态告知AMS
    ActivityClient.getInstance().activityPaused(token);
 }
//  frameworks\base\core\java\android\app\ActivityThread.java
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }
        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(r, finished, reason, pendingActions);
        ....
    }
}

接着调用performPauseActivity

 private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
        PendingTransactionActions pendingActions) {
    ....
    final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
    if (shouldSaveState) {
        // android 3之前会在on Pause之前调用onSaveInstanceState周期
        callActivityOnSaveInstanceState(r);
    }
    performPauseActivityIfNeeded(r, reason);
     .....
    return shouldSaveState ? r.state : null;
}

performPauseActivityIfNeeded中调用callActivityOnPause方法

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    ....
    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);
    } catch (SuperNotCalledException e) {
    }
    .....
}

InstrumentationcallActivityOnPause方法是直接掉用activity的performPause

1.3 回调通知AMS pause完毕

在PauseActivityItem的postExecute 方法中,会通过IActivityClientController 接口通知到ActivityClientController

ActivityClientController中就是调用ActivityRecordactivityPaused()方法

//frameworks\base\services\core\java\com\android\server\wm\ActivityClientController.java

    public void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized (mGlobalLock) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
            if (r != null) {
                r.activityPaused(false);
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        Binder.restoreCallingIdentity(origId);
    }

ActivityRecordactivityPaused()中,主要是取消pause的超时并通知TaskFragment更新ActivityRecord的生命周期状态。

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

    void activityPaused(boolean timeout) {
        ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", token,
                timeout);

        final TaskFragment taskFragment = getTaskFragment();
        if (taskFragment != null) {
            // 移除Pause的超时
            removePauseTimeout();

            final ActivityRecord pausingActivity = taskFragment.getPausingActivity();
            if (pausingActivity == this) {
                ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
                        (timeout ? "(due to timeout)" : " (pause complete)"));
                mAtmService.deferWindowLayout();
                try {
                    // 通知taskFragment,完成pause周期
                    taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
                } finally {
                    mAtmService.continueWindowLayout();
                }
                return;
            } else {
                ....
                if (isState(PAUSING)) {
                    setState(PAUSED, "activityPausedLocked"); // 更新ActivityRecord 生命周期状态
                    if (finishing) {
                        ProtoLog.v(WM_DEBUG_STATES,
                                "Executing finish of failed to pause activity: %s", this);
                        completeFinishing("activityPausedLocked");
                    }
                }
            }
        }

        mDisplayContent.handleActivitySizeCompatModeIfNeeded(this);
        mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
    }
// frameworks\base\services\core\java\com\android\server\wm\TaskFragment.java

void completePause(boolean resumeNext, ActivityRecord resuming) {
    ActivityRecord prev = mPausingActivity;
    if (prev != null) {
       if (prev.hasProcess()) {
          if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) {
                prev.setDeferHidingClient(false);
                // 添加到stopping状态
                prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
                        "completePauseLocked");
            }
        } 
    }
    if (resumeNext) { // 需要启动下一个activity
        final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
        if (topRootTask != null && !topRootTask.shouldSleepOrShutDownActivities()) {
            // 通知启动下一个activity
            mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,
                    null /* targetOptions */);
        } 
    }
}

2、onStop

2.1 应用

在新activity走完onResume后,会调用到上个activity的onStop。

 public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
         boolean isForward, String reason) {
     // 准备调用Resume周期
     final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
     ....
     Looper.myQueue().addIdleHandler(new Idler());
 }

在上一个Activity handleResumeActivity的最后,会注册一个Idler接口,该接口会在handler空闲的时候调用

    private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            
            if (a != null) {
                mNewActivities = null;
                final ActivityClient ac = ActivityClient.getInstance();
                ActivityClientRecord prev;
                do {
                    ....
                    if (a.activity != null && !a.activity.mFinished) {
                        // 调用ActivityClientController 的activityIdle
                        ac.activityIdle(a.token, a.createdConfig, stopProfiling);
                        a.createdConfig = null;
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            
            applyPendingProcessState();
            return false;
        }
    }

2.2 AMS 发起stop

轻车熟路找到ActivityClientController

//frameworks\base\services\core\java\com\android\server\wm\ActivityClientController.java

	public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
        final long origId = Binder.clearCallingIdentity();
        ....
        try {
            synchronized (mGlobalLock) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
                if (r == null) {
                    return;
                }
                mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */,
                        false /* processPausingActivities */, config);
                if (stopProfiling && r.hasProcess()) {
                    r.app.clearProfilerIfNeeded();
                }
            }
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            Binder.restoreCallingIdentity(origId);
        }
    }

调用到ActivityTaskSupervisor的activityIdleInternal

// frameworks\base\services\core\java\com\android\server\wm\ActivityTaskSupervisor.java

void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
        boolean processPausingActivities, Configuration config) {
    if (r != null) {
        ....
        // 移除超时的消息
        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
        ....
        r.mRelaunchReason = RELAUNCH_REASON_NONE;
    }
    ....
    // 调用上一个activity的onStop
    processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
}

processStoppingAndFinishingActivities方法用于处理Activity停止或销毁。这应该是闲置或绘制时调用恢复活动。

private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
        boolean processPausingActivities, String reason) {
    ....
    final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
    for (int i = 0; i < numReadyStops; i++) {
        final ActivityRecord r = readyToStopActivities.get(i);
        if (r.isInHistory()) {
            if (r.finishing) {
                // 被标记为finishing,则调用销毁的周期
                r.destroyIfPossible(reason);
            } else {
                // 调用onStop的周期。
                r.stopIfPossible();
            }
        }
    }
    ....
}

我们先看stopIfPossible方法

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

void stopIfPossible() {
    final Task rootTask = getRootTask();
    try {
        stopped = false;
        // 向app端发送StopActivityItem 周期
        setState(STOPPING, "stopIfPossible");
        mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
                StopActivityItem.obtain(configChangeFlags));
        // 添加超时的计时
        mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
    } catch (Exception e) {
    }
    .....
}
posted @ 2024-03-12 10:35  xtLLL  阅读(125)  评论(0编辑  收藏  举报