Android | 基於Android9.0的startActivity流程分析(4):原Activity的onStop、onSaveInstanceState流程

目錄

5. 原Activity的onStop流程

5.1 ActivityStackSupervisor.scheduleIdleLocked

5.2 ActivityStackSupervisor.ActivityStackSupervisorHandler.handleMessage

5.3 ActivityStackSupervisor.activityIdleInternalLocked

5.4 ActivityStack.stopActivityLocked

5.5 StopActivityItem.execute

5.5.1 ActivityThread.handleStopActivity

5.5.2 Activity.performStop

5.5.3 ActivityThread.callActivityOnSaveInstanceState

5.6 StopActivityItem.postExecute


Activity啓動流程的文章開篇的時候就說過,使用startActivity(Intent intent)方式啓動的activity有如下流程

  • 原Activity的onPause
  • 新Activity的onCreate
  • 新Activity的onStart
  • 新Activity的onResume
  • 原Activity的onStop
  • 原Activity的onSaveInstanceState

綠色部分的流程已經分析過了,現在就差原Activity的onStop和onSaveInstanceState流程了。

5. 原Activity的onStop流程

因爲該流程涉及到跨進程調用以及WMS中的窗口管理,使用打印堆棧的方式,會有大量的lambda表達式,整個流程追蹤起來較難。

目前從直接調用的地方回溯調用流程,分析到了如下的流程。如果有對完整流程熟悉的,煩請指教。

5.1 ActivityStackSupervisor.scheduleIdleLocked

重點:執行stopActivity的操作其實是通過ActivityStackSupervisor.ActivityStackSupervisorHandler中處理消息IDLE_NOW_MSG來完成的。而發送該消息的是ActivityStackSupervisor中的scheduleIdleLocked函數。

// /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
final ActivityStackSupervisorHandler mHandler;

final void scheduleIdleLocked() {
    mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}

處理IDLE_NOW_MSG消息的是ActivityStackSupervisorHandler:

5.2 ActivityStackSupervisor.ActivityStackSupervisorHandler.handleMessage

// /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
private final class ActivityStackSupervisorHandler extends Handler {

	void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
        synchronized (mService) {
            activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
                    processPausingActivities, null);
        }
    }
	
	@Override
    public void handleMessage(Message msg) {
		 switch (msg.what) {
			...
			case IDLE_NOW_MSG: {
                if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
                activityIdleInternal((ActivityRecord) msg.obj,
                    false /* processPausingActivities */);
            } break;
			...
		 }
	}
}

此處調用了activityIdleInternalLocked函數:

5.3 ActivityStackSupervisor.activityIdleInternalLocked

// /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
// Checked.
@GuardedBy("mService")
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) { //【r=null,該代碼不執行】
        ......
    }

    if (allResumedActivitiesIdle()) { //【返回值爲true】
        if (r != null) { //r=null
            mService.scheduleAppGcsLocked();
        }

        if (mLaunchingActivity.isHeld()) { //【mLaunchingActivity.isHeld()=false】
            mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
            if (VALIDATE_WAKE_LOCK_CALLER &&
                    Binder.getCallingUid() != Process.myUid()) {
                throw new IllegalStateException("Calling must be system uid");
            }
            mLaunchingActivity.release();
        }
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }

    // Atomically retrieve all of the other things to do.
    final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
            true /* remove */, processPausingActivities);
    NS = stops != null ? stops.size() : 0;
    if ((NF = mFinishingActivities.size()) > 0) { //【NS=1,mFinishingActivities.size()=0】
        finishes = new ArrayList<>(mFinishingActivities);
        mFinishingActivities.clear();
    }

    if (mStartingUsers.size() > 0) { //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++) { //【NS=1,所以for循環中的代碼會執行】
        r = stops.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) { //【stack不爲空】
            if (r.finishing) { //【r.finishing=false】
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
                        "activityIdleInternalLocked");
            } else {
                stack.stopActivityLocked(r); //【關鍵操作】調用了AtivityStack.stopActivityLocked函數來執行原Activity的onStop流程
            }
        }
    }

    // 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++) { //【NF=0】
        r = finishes.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) {
            activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
        }
    }

    if (!booting) { //booting=false
        // Complete user switch
        if (startingUsers != null) { //【startingUsers=null】
            for (int i = 0; i < startingUsers.size(); i++) {
                mService.mUserController.finishUserSwitch(startingUsers.get(i));
            }
        }
    }

    mService.trimApplications();
    //dump();
    //mWindowManager.dump();

    if (activityRemoved) { //【activityRemoved=false】
        resumeFocusedStackTopActivityLocked();
    }

    return r;
}

這個函數中的關鍵操作就是當NS = 1時,執行的ActivityStack.stopActivityLocked函數。

5.4 ActivityStack.stopActivityLocked

// /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
final void stopActivityLocked(ActivityRecord r) {
        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
            ......
        }

        if (r.app != null && r.app.thread != null) {
            adjustFocusedActivityStack(r, "stopActivity");
            r.resumeKeyDispatchingLocked();
            try {
                r.stopped = false;
                if (DEBUG_STATES) Slog.v(TAG_STATES,
                        "Moving to STOPPING: " + r + " (stop requested)");
                r.setState(STOPPING, "stopActivityLocked"); //【將Activity的狀態設置爲STOPPING】
                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                        "Stopping visible=" + r.visible + " for " + r);
                if (!r.visible) {
                    r.setVisible(false);
                }
                EventLogTags.writeAmStopActivity(
                        r.userId, System.identityHashCode(r), r.shortComponentName);
                mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
                        StopActivityItem.obtain(r.visible, r.configChangeFlags)); //【關鍵操作】將StopActivityItem作爲參數傳入
                if (shouldSleepOrShutDownActivities()) {
                    r.setSleeping(true);
                }
                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r); 
                mHandler.sendMessageDelayed(msg, STOP_TIMEOUT); //【設置STOP_TIMEOUT超時消息】
            } catch (Exception e) {
                // Maybe just ignore exceptions here...  if the process
                // has crashed, our death notification will clean things
                // up.
                Slog.w(TAG, "Exception thrown during pause", e);
                // Just in case, assume it to be stopped.
                r.stopped = true;
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
                r.setState(STOPPED, "stopActivityLocked");
                if (r.deferRelaunchUntilPaused) {
                    destroyActivityLocked(r, true, "stop-except");
                }
            }
        }
    }

現在要看的關鍵操作是ClientLifecycleManager.scheduleTransaction函數,因爲此前的每個生命週期流程都涉及到該流程,所以此處僅貼函數調用流程的源碼以供理解。

//  /frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java
     /**
     * Schedule a single lifecycle request or callback to client activity.
     * @param client Target client.
     * @param activityToken Target activity token.
     * @param stateRequest A request to move target activity to a desired lifecycle state.
     * @throws RemoteException
     *
     * @see ClientTransactionItem
     */
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }

    /**
     * @return A new instance of {@link ClientTransaction} with a single lifecycle state request.
     *
     * @see ClientTransaction
     * @see ClientTransactionItem
     */
    private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        clientTransaction.setLifecycleStateRequest(stateRequest); //【將StopActivityItem設置到clientTransaction中】
        return clientTransaction;
    }

    /**
     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
     * @param transaction A sequence of client transaction items.
     * @throws RemoteException
     *
     * @see ClientTransaction
     */
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule(); //【調用ClientTransaction.schedule函數】
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

接着是ClientTransaction.schedule函數:

// /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
    /**
     * Schedule the transaction after it was initialized. It will be send to client and all its
     * individual parts will be applied in the following sequence:
     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
     *    that needs to be done before actually scheduling the transaction for callbacks and
     *    lifecycle state request.
     * 2. The transaction message is scheduled.
     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
     *    all callbacks and necessary lifecycle transitions.
     */
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this); //【跨進程,由應用進程的binder線程(即ActivityThread.ApplicaitonThread)完成】
    }

接着看看ActivityThread.ApplicationThread.scheduleTransaction函數:

// /frameworks/base/core/java/android/app/ActivityThread.java        
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
// /frameworks/base/core/java/android/app/ClientTransactionHandler.java
    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
///frameworks/base/core/java/android/app/ActivityThread.java

    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

     void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

     private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg); //【ActivityThread.H中處理該消息】
    }

   
  private class ApplicationThread extends IApplicationThread.Stub {
       ...
        public void handleMessage(Message msg) {
            ...
            case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;
            ...
        }
  }
///frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
    /**
     * Resolve transaction.
     * First all callbacks will be executed in the order they appear in the list. If a callback
     * requires a certain pre- or post-execution state, the client will be transitioned accordingly.
     * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
     * either remain in the initial state, or last state needed by a callback.
     */
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
 
        executeCallbacks(transaction);
 
        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }

同樣地,完成的主要操作:

  • executeCallbacks:此前並未addCallback,所以該函數沒有特別需要說明的
  • executeLifecycleState:此前將StopActivityItem設置到了ClientTransaction中。

來看看executeLifecycleState函數:

// /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
     /** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();//【lifeycleItem即是此前設的StopActivityItem對象】
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        log("Resolving lifecycle state: " + lifecycleItem);
 
        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
 
        if (r == null) {
            // Ignore requests for non-existent client records for now.
            return;
        }
 
        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */); //【該函數中的path.size =0】
 
        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

該函數完成的主要工作爲:

  • StopActivityItem.execute
  • StopActivityItem.postExecute

5.5 StopActivityItem.execute

所以接下來看看StopActivityItem.execute函數:

// /frameworks/base/core/java/android/app/servertransaction/StopActivityItem.java
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
        client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
                true /* finalStateRequest */, "STOP_ACTIVITY_ITEM"); //【實質調用了ActivityThread.handleStopActivity】
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

來看看ActivityThread.handleStopActivity函數:

5.5.1 ActivityThread.handleStopActivity

// /frameworks/base/core/java/android/app/ActivityThread.java
     @Override
    public void handleStopActivity(IBinder token, boolean show, int configChanges,
            PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
        final ActivityClientRecord r = mActivities.get(token);
        r.activity.mConfigChangeFlags |= configChanges;

        final StopInfo stopInfo = new StopInfo();
        performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
                reason); //【關鍵操作】

        if (localLOGV) Slog.v(
            TAG, "Finishing stop of " + r + ": show=" + show
            + " win=" + r.window);

        updateVisibility(r, show);

        // Make sure any pending writes are now committed.
        if (!r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }

        stopInfo.setActivity(r);
        stopInfo.setState(r.state);
        stopInfo.setPersistentState(r.persistentState);
        pendingActions.setStopInfo(stopInfo);
        mSomeActivitiesChanged = true;
    }

接着看看performStopActivityInner函數:

// 
    /**
     * Core implementation of stopping an activity.  Note this is a little
     * tricky because the server's meaning of stop is slightly different
     * than our client -- for the server, stop means to save state and give
     * it the result when it is done, but the window may still be visible.
     * For the client, we want to call onStop()/onStart() to indicate when
     * the activity's UI visibility changes.
     * @param r Target activity client record.
     * @param info Action that will report activity stop to server.
     * @param keepShown Flag indicating whether the activity is still shown.
     * @param saveState Flag indicating whether the activity state should be saved.
     * @param finalStateRequest Flag indicating if this call is handling final lifecycle state
     *                          request for a transaction.
     * @param reason Reason for performing this operation.
     */
    private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
            boolean saveState, boolean finalStateRequest, String reason) {
        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
        if (r != null) {
            if (!keepShown && r.stopped) {
                if (r.activity.mFinished) {
                    // If we are finishing, we won't call onResume() in certain
                    // cases.  So here we likewise don't want to call onStop()
                    // if the activity isn't resumed.
                    return;
                }
                if (!finalStateRequest) {
                    final RuntimeException e = new RuntimeException(
                            "Performing stop of activity that is already stopped: "
                                    + r.intent.getComponent().toShortString());
                    Slog.e(TAG, e.getMessage(), e);
                    Slog.e(TAG, r.getStateString());
                }
            }

            // One must first be paused before stopped...
            performPauseActivityIfNeeded(r, reason); 【stop操作之前必須是pause操作完成】

            if (info != null) {
                try {
                    // First create a thumbnail for the activity...
                    // For now, don't create the thumbnail here; we are
                    // doing that by doing a screen snapshot.
                    info.setDescription(r.activity.onCreateDescription());
                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
                                "Unable to save state of activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
                    }
                }
            }

            if (!keepShown) {
                callActivityOnStop(r, saveState, reason); 【關鍵操作】
            }
        }
    }

該函數主要完成的操作:

  • performPauseActivityIfNeeded:先查看是否爲pause狀態,如果不是就要先pause
  • callActivityOnStop

先看performPauseActivityIfNeeded函數:

// /frameworks/base/core/java/android/app/ActivityThread.java
    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        if (r.paused) { //因爲此前已經pause過,所以此處的之後爲true,直接return
            // You are already paused silly...
            return;
        }

        try {
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnPause(r.activity);
            if (!r.activity.mCalled) {
                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                        + " did not call through to super.onPause()");
            }
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException("Unable to pause activity "
                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
            }
        }
        r.setState(ON_PAUSE);
    }

再看看callActivityOnStop:

// /frameworks/base/core/java/android/app/ActivityThread.java
    /**
     * Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates
     * the client record's state.
     * All calls to stop an activity must be done through this method to make sure that
     * {@link Activity#onSaveInstanceState(Bundle)} is also executed in the same call.
     */
    private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
        // Before P onSaveInstanceState was called before onStop, starting with P it's
        // called after. Before Honeycomb state was always saved before onPause.
        final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
                && !r.isPreHoneycomb();
        final boolean isPreP = r.isPreP();
        if (shouldSaveState && isPreP) { //shouldSaveState=true,isPreP=false
            callActivityOnSaveInstanceState(r);
        }

        try {
            r.activity.performStop(false /*preserveWindow*/, reason); //【關鍵操作】
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException(
                        "Unable to stop activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
            }
        }
        r.setState(ON_STOP); //【將Activity的狀態設置爲ON_STOP】

        if (shouldSaveState && !isPreP) { //【shouldSaveState=true,isPreP=false】
            callActivityOnSaveInstanceState(r); //【關鍵操作】
        }
    }

該函數的主要操作:

  • Activity.performStop
  • ActivityThread.callActivityOnSaveInstanceState

5.5.2 Activity.performStop

// /frameworks/base/core/java/android/app/Activity.java
     final void performStop(boolean preserveWindow, String reason) {
        mDoReportFullyDrawn = false;
        mFragments.doLoaderStop(mChangingConfigurations /*retain*/);

        // Disallow entering picture-in-picture after the activity has been stopped
        mCanEnterPictureInPicture = false;

        if (!mStopped) { //【mStopped = false】
            if (mWindow != null) {
                mWindow.closeAllPanels();
            }

            // If we're preserving the window, don't setStoppedState to true, since we
            // need the window started immediately again. Stopping the window will
            // destroys hardware resources and causes flicker.
            if (!preserveWindow && mToken != null && mParent == null) {
                WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
            }

            mFragments.dispatchStop(); //【Fragment的stop相關的操作】

            mCalled = false;
            mInstrumentation.callActivityOnStop(this); //【關鍵操作】
            writeEventLog(LOG_AM_ON_STOP_CALLED, reason);
            if (!mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + mComponent.toShortString() +
                    " did not call through to super.onStop()");
            }

            synchronized (mManagedCursors) {
                final int N = mManagedCursors.size();
                for (int i=0; i<N; i++) {
                    ManagedCursor mc = mManagedCursors.get(i);
                    if (!mc.mReleased) {
                        mc.mCursor.deactivate();
                        mc.mReleased = true;
                    }
                }
            }

            mStopped = true;
        }
        mResumed = false;
    }

關鍵操作是調用了Instrumentation.callActivityOnStop函數:

// /frameworks/base/core/java/android/app/Instrumentation.java
    /**
     * Perform calling of an activity's {@link Activity#onStop}
     * method.  The default implementation simply calls through to that method.
     *
     * @param activity The activity being stopped.
     */
    public void callActivityOnStop(Activity activity) {
        activity.onStop(); //【完成了Activity.onStop操作】
    }

至此,Activity的onStop操作被執行。

5.5.3 ActivityThread.callActivityOnSaveInstanceState

// /frameworks/base/core/java/android/app/ActivityThread.java
    private void callActivityOnSaveInstanceState(ActivityClientRecord r) {
        r.state = new Bundle();
        r.state.setAllowFds(false);
        if (r.isPersistable()) { //【r.isPersistable()=false】
            r.persistentState = new PersistableBundle();
            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
                    r.persistentState);
        } else {
            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); //【關鍵操作】
        }
    }
///frameworks/base/core/java/android/app/Instrumentation.java
    /**
     * Perform calling of an activity's {@link Activity#onSaveInstanceState}
     * method.  The default implementation simply calls through to that method.
     *
     * @param activity The activity being saved.
     * @param outState The bundle to pass to the call.
     */
    public void callActivityOnSaveInstanceState(Activity activity, Bundle outState) {
        activity.performSaveInstanceState(outState);
    }
// /frameworks/base/core/java/android/app/Activity.java
    /**
     * The hook for {@link ActivityThread} to save the state of this activity.
     *
     * Calls {@link #onSaveInstanceState(android.os.Bundle)}
     * and {@link #saveManagedDialogs(android.os.Bundle)}.
     *
     * @param outState The bundle to save the state to.
     */
    final void performSaveInstanceState(Bundle outState) {
        onSaveInstanceState(outState); //【onSaveInstanceState被調用】
        saveManagedDialogs(outState);
        mActivityTransitionState.saveState(outState);
        storeHasCurrentPermissionRequest(outState);
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
    }

至此,Activity的onSaveInstanceState函數被調用。

5.6 StopActivityItem.postExecute

// /frameworks/base/core/java/android/app/servertransaction/StopActivityItem.java
    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        client.reportStop(pendingActions);
    }
///frameworks/base/core/java/android/app/ActivityThread.java
    /**
     * Schedule the call to tell the activity manager we have stopped.  We don't do this
     * immediately, because we want to have a chance for any other pending work (in particular
     * memory trim requests) to complete before you tell the activity manager to proceed and allow
     * us to go fully into the background.
     */
    @Override
    public void reportStop(PendingTransactionActions pendingActions) {
        mH.post(pendingActions.getStopInfo());
    }

那麼pendingActions.getStopInfo()是什麼東西呢?

//  /frameworks/base/core/java/android/app/servertransaction/PendingTransactionActions.java
    public StopInfo getStopInfo() {
        return mStopInfo;
    }

    /** Reports to server about activity stop. */
    public static class StopInfo implements Runnable {
        @Override
        public void run() {
            // Tell activity manager we have been stopped.
            try {
                if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + mActivity);
                // TODO(lifecycler): Use interface callback instead of AMS.
                ActivityManager.getService().activityStopped(
                        mActivity.token, mState, mPersistentState, mDescription); //【跨進程調用AMS.activityStopped】
            } catch (RemoteException ex) {
                // Dump statistics about bundle to help developers debug
                final LogWriter writer = new LogWriter(Log.WARN, TAG);
                final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
                pw.println("Bundle stats:");
                Bundle.dumpStats(pw, mState);
                pw.println("PersistableBundle stats:");
                Bundle.dumpStats(pw, mPersistentState);

                if (ex instanceof TransactionTooLargeException
                        && mActivity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
                    Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
                    return;
                }
                throw ex.rethrowFromSystemServer();
            }
        }
    }

看看AMS.activityStopped函數:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    @Override
    public final void activityStopped(IBinder token, Bundle icicle,
            PersistableBundle persistentState, CharSequence description) {
        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);

        // Refuse possible leaked file descriptors
        if (icicle != null && icicle.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Bundle");
        }

        final long origId = Binder.clearCallingIdentity();

        synchronized (this) {
            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
            if (r != null) {
                r.activityStoppedLocked(icicle, persistentState, description); //【調用ActivityRecord.activityStoppedLocked】
            }
        }

        trimApplications();

        Binder.restoreCallingIdentity(origId);
    }

再來看看ActivityRecord.activityStoppedLocked函數:

// /frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
            CharSequence description) {
        final ActivityStack stack = getStack();
        if (mState != STOPPING) { //【mState = STOPPING】
            Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
            stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
            return;
        }
        if (newPersistentState != null) { //【newPersistentState=null】
            persistentState = newPersistentState;
            service.notifyTaskPersisterLocked(task, false);
        }
        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);

        if (newIcicle != null) { //【newIcicle 不爲null】
            // If icicle is null, this is happening due to a timeout, so we haven't really saved
            // the state.
            icicle = newIcicle;
            haveState = true;
            launchCount = 0;
            updateTaskDescription(description);
        }
        if (!stopped) { //【stopped=false】
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
            stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
            stopped = true;
            setState(STOPPED, "activityStoppedLocked");

            mWindowContainerController.notifyAppStopped();

            if (finishing) { //【finishing=false】
                clearOptionsLocked();
            } else {
                if (deferRelaunchUntilPaused) { //【deferRelaunchUntilPaused=false】
                    stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                } else {
                    mStackSupervisor.updatePreviousProcessLocked(this);
                }
            }
        }
    }

到這裏,前臺Activity中啓動新的Activity的流程就結束了。

下面是整個流程的思維導圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章