Android 进程存在的Activity启动

我们知道,Activity A启动Activity B时,是先将A暂停(执行生命周期onPause),然后会执行B的onCreate、OnStart、OnResume方法,之后再执行A的onStop。如果启动B时,它的进程不存在,会先将它的进程启动起来,再执行它的生命周期。

咱们先看简单情况下,就是不涉及进程创建这种情况下的生命周期。之前一篇文章 Android 系统进程启动Activity方法说明指出,Activity的暂停是由Task的startPausingLocked方法执行的,咱们看下它的实现。

暂停Activity

Task的startPausingLocked方法如下:

java 复制代码
    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, String reason) {
        if (!isLeafTask()) {
            final int[] pausing = {0};
            forAllLeafTasks((t) -> {
                if (t.startPausingLocked(userLeaving, uiSleeping, resuming, reason)) {
                    pausing[0]++;
                }
            }, true /* traverseTopToBottom */);
            return pausing[0] > 0;
        }

        if (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) {
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mRootWindowContainer.resumeFocusedTasksTopActivities();
            }
            return false;
        }

        if (prev == resuming) {
            Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
            return false;
        }

        ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev);
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        if (prev.isNoHistory() && !mTaskSupervisor.mNoHistoryActivities.contains(prev)) {
            mTaskSupervisor.mNoHistoryActivities.add(prev);
        }
        prev.setState(PAUSING, "startPausingLocked");
        prev.getTask().touchActiveTime();

        mAtmService.updateCpuStats();

        boolean pauseImmediately = false;
        boolean shouldAutoPip = false;
        if (resuming != null && (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0) {
            // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous
            // activity to be paused, while at the same time resuming the new resume activity
            // only if the previous activity can't go into Pip since we want to give Pip
            // activities a chance to enter Pip before resuming the next activity.
            final boolean lastResumedCanPip = prev != null && prev.checkEnterPictureInPictureState(
                    "shouldResumeWhilePausing", userLeaving);
            if (lastResumedCanPip && prev.pictureInPictureArgs.isAutoEnterEnabled()) {
                shouldAutoPip = true;
            } else if (!lastResumedCanPip) {
                pauseImmediately = true;
            } else {
                // The previous activity may still enter PIP even though it did not allow auto-PIP.
            }
        }

        boolean didAutoPip = false;
        if (prev.attachedToProcess()) {
            if (shouldAutoPip) {
                ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
                        + "directly: %s", prev);

                didAutoPip = mAtmService.enterPictureInPictureMode(prev, prev.pictureInPictureArgs);
                mPausingActivity = null;
            } else {
                ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
                try {
                    EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                            prev.shortComponentName, "userLeaving=" + userLeaving, reason);

                    mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                            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;
                    mTaskSupervisor.mNoHistoryActivities.remove(prev);
                }
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mTaskSupervisor.mNoHistoryActivities.remove(prev);
        }

        // If we are not going to sleep, we want to ensure the device is
        // awake until the next activity is started.
        if (!uiSleeping && !mAtmService.isSleepingOrShuttingDownLocked()) {
            mTaskSupervisor.acquireLaunchWakelock();
        }

        // If already entered PIP mode, no need to keep pausing.
        if (mPausingActivity != null && !didAutoPip) {
            // 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) {
                prev.pauseKeyDispatchingLocked();
            } else {
                ProtoLog.v(WM_DEBUG_STATES, "Key dispatch not paused for screen off");
            }

            if (pauseImmediately) {
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                completePauseLocked(false, resuming);
                return false;

            } else {
                prev.schedulePauseTimeout();
                return true;
            }

        } else {
            // This activity either failed to schedule the pause or it entered PIP mode,
            // so just treat it as being paused now.
            ProtoLog.v(WM_DEBUG_STATES, "Activity not running or entered PiP, resuming next.");
            if (resuming == null) {
                mRootWindowContainer.resumeFocusedTasksTopActivities();
            }
            return false;
        }
    }

如果不是叶子任务,使用forAllLeafTasks循环到所有的叶子任务,然后调用它的startPausingLocked方法,如果该方法返回true,则将pausing[0]加1,最后循环结束后,检查pausing[0] > 0,只要有返回true,说明就有Task在执行Activity的暂停中。

mPausingActivity不为null,意味着,该Task正在暂停Activity过程中,所以在设备不睡眠的情况下,调用completePauseLocked(false, resuming)完成暂停工作。

接着将mResumedActivity赋值给变量prev。任务暂停的主要任务就是将mResumedActivity给暂停。

如果prev为null,并且resuming也为null,代表没有需要暂停的Activity,也没有需要恢复的Activity,调用mRootWindowContainer.resumeFocusedTasksTopActivities()试着恢复其他任务的Activity。这种情况,直接返回false。

如果prev==resuming,说明暂停和恢复的Activity都一样,这种情况也不行,直接返回false。

注意,看到给mPausingActivity赋值了,将它设置为prev,也就是mResumedActivity。

也给mLastPausedActivity赋值。

如果prev是没有历史记录,这里会将它加入到mTaskSupervisor.mNoHistoryActivities中。对于没有历史记录的Activity,主要是它处于停止状态,就把它们完成finished。

接着将prev设置为PAUSING状态,代表是在暂停中。

任务的touchActiveTime()是设置它的lastActiveTime为当前启动时间。

接着调用mAtmService.updateCpuStats()更新CPU状态。

如果待启动的Activity设置了FLAG_RESUME_WHILE_PAUSING标识,会检查prev能否进入PIP模式。如果可以进入,并且相关参数设置了可以自动进入,将shouldAutoPip = true,代表可以进入PIP。如果不能进入PIP模式,将pauseImmediately = true,代表需要立即执行暂停,不等待暂停完成。如果可以进入,但是没有设置自动进入,就像正常的Activity处理。

接着,如果prev已经绑定进程了,它会检查能否进入PIP模式。

1、可以进入PIP模式。检查刚才的shouldAutoPip,它为true,就调用mAtmService.enterPictureInPictureMode方法让它进入PIP模式,返回结果didAutoPip是否进入。并将mPausingActivity = null。

2、不进入PIP模式,调用ClientLifecycleManager对象的scheduleTransaction方法,去应用端执行Activity的暂停周期。该种情况下,就需要等待应用端执行完毕,给系统进程响应。

如果prev没有绑定进程,这里的处理,将mPausingActivity = null。将prev从mTaskSupervisor.mNoHistoryActivities删除。

如果系统不是进入睡眠,就确保设备唤醒直到下个Activity启动,唤醒是mTaskSupervisor.acquireLaunchWakelock()执行。

mPausingActivity != null && !didAutoPip,这个条件满足,代表没有进入PIP模式。

在这个条件下,如果屏幕没有关闭,调用prev.pauseKeyDispatchingLocked(),暂停prev的按键派发事件。

如果pauseImmediately为true,代表立即执行暂停行为,所以直接调用completePauseLocked(false, resuming),完成暂停工作。这里的第一个参数为false,代表完成暂停之后,不继续恢复其他Activity执行。接着返回false。

如果pauseImmediately为false,这里发送一个等待超时消息,超时时间为500ms。如果到时没有收到应用程序应答,这里会执行超时处理。接着返回结果true。

最后这个else里的情况,是调用ClientLifecycleManager对象的scheduleTransaction方法失败,或者进入PIP模式。如果resuming == null,调用mRootWindowContainer.resumeFocusedTasksTopActivities()重新执行恢复Activity。最后,返回false。

这个方法返回true,就是调用ClientLifecycleManager对象的scheduleTransaction方法之后,等待Activity暂停完成。

返回false的情况则是和上面的相反的情况,有以下几种情况,1、prev、resuming条件不符合。2、进入PIP模式。3、立即执行暂停完成。4、ClientLifecycleManager对象的scheduleTransaction方法执行异常。

像这个第2、3种情况,是需要参数resuming存在FLAG_RESUME_WHILE_PAUSING标识才出现的。

应用程序执行暂停

它在系统进程端是由ClientLifecycleManager对象的scheduleTransaction方法执行的

java 复制代码
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.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();
        }
    }

    /**
     * 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);
    }

参数里的stateRequest是PauseActivityItem.obtain(prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately),通过transactionWithState方法封装成ClientTransaction 对象。其中client是IApplicationThread ,它是应用进程端对应进程ApplicationThread的Binder代理对象,通过它可以与应用进程端通信。transaction.schedule()就是通过它的scheduleTransaction方法进入到应用进程端ApplicationThread的scheduleTransaction(ClientTransaction transaction)方法的,ApplicationThread在ActivityThread类里,看一下它的实现:

java 复制代码
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

ActivityThread类继承ClientTransactionHandler类,scheduleTransaction方法就是在它里面实现的

java 复制代码
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

可以看到在Binder线程中执行了transaction.preExecute(this),就直接发送EXECUTE_TRANSACTION消息,切换到应用的主线程中去执行了,而Binder线程也就执行完返回应答了。

transaction.preExecute(this)的代码看下:

java 复制代码
    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i < size; ++i) {
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }

如果mActivityCallbacks存在,在这里调用它的preExecute方法,注意这里是在应用进程端执行的。

这里的mLifecycleStateRequest 是PauseActivityItem对象,它的preExecute是一个空实现。

接着咱们进入到应用进程端看下ActivityThread.H.EXECUTE_TRANSACTION的消息处理,它在ActivityThread类中H 类的handleMessage处理,看下它的实现:

java 复制代码
                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;

mTransactionExecutor是TransactionExecutor类,看下它的execute(transaction)实现:

java 复制代码
    public void execute(ClientTransaction transaction) {
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");

        final IBinder token = transaction.getActivityToken();
        if (token != null) {
            final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
                    mTransactionHandler.getActivitiesToBeDestroyed();
            final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
            if (destroyItem != null) {
                if (transaction.getLifecycleStateRequest() == destroyItem) {
                    // It is going to execute the transaction that will destroy activity with the
                    // token, so the corresponding to-be-destroyed record can be removed.
                    activitiesToBeDestroyed.remove(token);
                }
                if (mTransactionHandler.getActivityClient(token) == null) {
                    // The activity has not been created but has been requested to destroy, so all
                    // transactions for the token are just like being cancelled.
                    Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
                            + transactionToString(transaction, mTransactionHandler));
                    return;
                }
            }
        }

        if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }

mTransactionHandler就是ActivityThread对象,开始那些代码是处理Destory周期相关代码。

下面就是调用executeCallbacks(transaction),它是用来执行ClientTransaction对象添加的回调事件,像ActivityResultItem、NewIntentItem,它们分别对应着Activity中onActivityResult、onNewIntent方法的调用。

executeLifecycleState(transaction)就是用来执行Activity的生命周期的,看下它的实现:

java 复制代码
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }

        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
                    + lifecycleItem + " for activity: "
                    + getShortActivityName(token, mTransactionHandler));
        }

        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 */, transaction);

        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

这里transaction.getLifecycleStateRequest()得到的lifecycleItem是PauseActivityItem对象,通过token得到在应用端的ActivityClientRecord 对象r。

cycleToPath方法是用来处理Activity生命周期的,第三个参数表示是否执行最后一个状态的生命周期,如果为true,不执行。最后一个的生命周期就是通过下面lifecycleItem.execute来执行的。

最后执行lifecycleItem.postExecute方法,PauseActivityItem的类的处理是通知系统进程它暂停完了。

看下cycleToPath方法的实现:

java 复制代码
    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Cycle activity: "
                    + getShortActivityName(r.token, mTransactionHandler)
                    + " from: " + getStateName(start) + " to: " + getStateName(finish)
                    + " excludeLastState: " + excludeLastState);
        }
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path, transaction);
    }

start 是Activity开始的生命周期,finish是Activity最后要完成的生命周期,所以mHelper.getLifecyclePath方法来计算出来要经过哪些生命周期,计算出来放到IntArray 类型变量path 中。

像我们这个暂停周期,因为Activity目前是onResume,并且excludeLastState目前为true,需要排除掉onPause,所以path 是空的,不会执行。

performLifecycleSequence(r, path, transaction)就是来执行它的具体生命周期。看下它的实现:

java 复制代码
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            if (DEBUG_RESOLVER) {
                Slog.d(TAG, tId(transaction) + "Transitioning activity: "
                        + getShortActivityName(r.token, mTransactionHandler)
                        + " to state: " + getStateName(state));
            }
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions,
                            null /* activityOptions */);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
                            mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

mTransactionHandler就是ActivityThread对象,所以我们看到它根据生命周期路径值,来执行对应的生命周期。

接着看回我们的PauseActivityItem对象的execute方法。

java 复制代码
    @Override
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, pendingActions,
                "PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

这里client是ActivityThread对象,所以就执行到了它的handlePauseActivity方法。

java 复制代码
    @Override
    public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(r, finished, reason, pendingActions);

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

这里处理了userLeaving,如果它为true,会在onPause之前执行Activity的onUserLeaveHint()。

接着将配置更改并到Activity的mConfigChangeFlags 中。

执行performPauseActivity来执行Activity的onPause生命周期。

如果Activity的应用的targetSdkVersion小于HONEYCOMB,这里确保所有的写工作都被确认。

主要来看一下performPauseActivity方法

java 复制代码
    private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
            PendingTransactionActions pendingActions) {
        if (r.paused) {
            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 onPause() if the activity
                // isn't resumed.
                return null;
            }
            RuntimeException e = new RuntimeException(
                    "Performing pause of activity that is not resumed: "
                    + r.intent.getComponent().toShortString());
            Slog.e(TAG, e.getMessage(), e);
        }
        if (finished) {
            r.activity.mFinished = true;
        }

        // Pre-Honeycomb apps always save their state before pausing
        final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
        if (shouldSaveState) {
            callActivityOnSaveInstanceState(r);
        }

        performPauseActivityIfNeeded(r, reason);

        // Notify any outstanding on paused listeners
        ArrayList<OnActivityPausedListener> listeners;
        synchronized (mOnPauseListeners) {
            listeners = mOnPauseListeners.remove(r.activity);
        }
        int size = (listeners != null ? listeners.size() : 0);
        for (int i = 0; i < size; i++) {
            listeners.get(i).onPaused(r.activity);
        }

        final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null;
        if (oldState != null) {
            // We need to keep around the original state, in case we need to be created again.
            // But we only do this for pre-Honeycomb apps, which always save their state when
            // pausing, so we can not have them save their state when restarting from a paused
            // state. For HC and later, we want to (and can) let the state be saved as the
            // normal part of stopping the activity.
            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }

        return shouldSaveState ? r.state : null;
    }

如果ActivityClientRecord已经是paused,并且Activity已经是mFinished,直接返回,不再往下执行。

如果参数finished为true,这里将r.activity.mFinished = true,这里是将系统进程中的状态同步到应用进程中。

如果Activity的应用的targetSdkVersion小于HONEYCOMB,并且Activity不是mFinished,这时需要调用Activity的OnSaveInstanceState方法,来保存数据。

接着就是执行performPauseActivityIfNeeded方法,执行Activity的onPause方法。

下面是如果ActivityThread对象注册了OnActivityPausedListener回调,这里调用它。

接着看performPauseActivityIfNeeded方法,

java 复制代码
    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        if (r.paused) {
            // You are already paused silly...
            return;
        }

        // Always reporting top resumed position loss when pausing an activity. If necessary, it
        // will be restored in performResumeActivity().
        reportTopResumedActivityChanged(r, false /* onTop */, "pausing");

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

可以看到调用了mInstrumentation.callActivityOnPause(r.activity),mInstrumentation是Instrumentation对象,它直接执行Activity对象的performPause()方法。

最后调用了r.setState(ON_PAUSE)设置它的对应状态,他会将ActivityClientRecord 对象的paused = true,stopped = false。

主要看Activity对象的performPause()方法

java 复制代码
    final void performPause() {
        if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performPause:"
                    + mComponent.getClassName());
        }
        dispatchActivityPrePaused();
        mDoReportFullyDrawn = false;
        mFragments.dispatchPause();
        mCalled = false;
        onPause();
        EventLogTags.writeWmOnPausedCalled(mIdent, getComponentName().getClassName(),
                "performPause");
        mResumed = false;
        if (!mCalled && getApplicationInfo().targetSdkVersion
                >= android.os.Build.VERSION_CODES.GINGERBREAD) {
            throw new SuperNotCalledException(
                    "Activity " + mComponent.toShortString() +
                    " did not call through to super.onPause()");
        }
        dispatchActivityPostPaused();
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
    }

dispatchActivityPrePaused()是用来执行一些暂停前回调。

mFragments.dispatchPause()用来设置Activiyt中的Fragment对象的生命周期暂停。

调用Activity的onPause()生命周期方法。

mResumed = false

dispatchActivityPostPaused()是用来执行一些暂停后回调。

系统进程处理Activity暂停完毕

它是在PauseActivityItem的postExecute方法完成,看下它的实现:

java 复制代码
    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        if (mDontReport) {
            return;
        }
        // TODO(lifecycler): Use interface callback instead of actual implementation.
        ActivityClient.getInstance().activityPaused(token);
    }

如果mDontReport为true,则不通知系统进程。像立即执行暂停的Activity就不会执行下面的通知。

调用ActivityClient类对象的activityPaused方法,调用的是系统进程端ActivityClientController对象的代理对象的activityPaused方法。这里直接到ActivityClientController类中看下activityPaused方法的实现:

java 复制代码
    @Override
    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);
    }

这里通过参数token得到系统进程端的ActivityRecord ,直接执行它的activityPaused方法。看下它的方法

java 复制代码
    void activityPaused(boolean timeout) {
        ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", appToken,
                timeout);

        if (task != null) {
            removePauseTimeout();

            final ActivityRecord pausingActivity = task.getPausingActivity();
            if (pausingActivity == this) {
                ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
                        (timeout ? "(due to timeout)" : " (pause complete)"));
                mAtmService.deferWindowLayout();
                try {
                    task.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
                } finally {
                    mAtmService.continueWindowLayout();
                }
                return;
            } else {
                EventLogTags.writeWmFailedToPause(mUserId, System.identityHashCode(this),
                        shortComponentName, pausingActivity != null
                                ? pausingActivity.shortComponentName : "(none)");
                if (isState(PAUSING)) {
                    setState(PAUSED, "activityPausedLocked");
                    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);
    }

首先取消暂停的超时消息,调用的是removePauseTimeout()。

如果任务中pausingActivity和目前的相等,就去执行它的completePauseLocked方法,完成它的暂停工作。

如果不相等,它的状态如果为PAUSING(暂停中),将它的状态设置为PAUSED。并且如果Activity的finishing为true,调用completeFinishing方法结束它。

接着调用mDisplayContent.handleActivitySizeCompatModeIfNeeded(this)检查Activity是在兼容模式并且通知它的改变。

最后调用mRootWindowContainer.ensureActivitiesVisible方法,使所有Activity的可见性保持正确。

接着看任务的completePauseLocked方法,看它完成暂停工作。并且它的第一个参数为true,会暂停完成之后,就去执行新Activity的恢复执行。看下它的代码,在Task类中:

java 复制代码
    @VisibleForTesting
    void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        // Complete the pausing process of a pausing activity, so it doesn't make sense to
        // operate on non-leaf tasks.
        warnForNonLeafTask("completePauseLocked");

        ActivityRecord prev = mPausingActivity;
        ProtoLog.v(WM_DEBUG_STATES, "Complete pause: %s", prev);

        if (prev != null) {
            prev.setWillCloseOrEnterPip(false);
            final boolean wasStopping = prev.isState(STOPPING);
            prev.setState(PAUSED, "completePausedLocked");
            if (prev.finishing) {
                // We will update the activity visibility later, no need to do in
                // completeFinishing(). Updating visibility here might also making the next
                // activities to be resumed, and could result in wrong app transition due to
                // lack of previous activity information.
                ProtoLog.v(WM_DEBUG_STATES, "Executing finish of activity: %s", prev);
                prev = prev.completeFinishing(false /* updateVisibility */,
                        "completePausedLocked");
            } else if (prev.hasProcess()) {
                ProtoLog.v(WM_DEBUG_STATES, "Enqueue pending stop if needed: %s "
                        + "wasStopping=%b visibleRequested=%b",  prev,  wasStopping,
                        prev.mVisibleRequested);
                if (prev.deferRelaunchUntilPaused) {
                    // Complete the deferred relaunch that was waiting for pause to complete.
                    ProtoLog.v(WM_DEBUG_STATES, "Re-launching after pause: %s", prev);
                    prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
                } else if (wasStopping) {
                    // We are also stopping, the stop request must have gone soon after the pause.
                    // We can't clobber it, because the stop confirmation will not be handled.
                    // We don't need to schedule another stop, we only need to let it happen.
                    prev.setState(STOPPING, "completePausedLocked");
                } else if (!prev.mVisibleRequested || 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.
                    prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
                            "completePauseLocked");
                }
            } else {
                ProtoLog.v(WM_DEBUG_STATES, "App died during pause, not stopping: %s", 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;
        }

        if (resumeNext) {
            final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
            if (topRootTask != null && !topRootTask.shouldSleepOrShutDownActivities()) {
                mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev, null);
            } else {
                checkReadyForSleep();
                final ActivityRecord top =
                        topRootTask != null ? topRootTask.topRunningActivity() : null;
                if (top == null || (prev != null && top != prev)) {
                    // If there are no more activities available to run, do resume anyway to start
                    // something. Also if the top activity on the root task is not the just paused
                    // activity, we need to go ahead and resume it to ensure we complete an
                    // in-flight app switch.
                    mRootWindowContainer.resumeFocusedTasksTopActivities();
                }
            }
        }

        if (prev != null) {
            prev.resumeKeyDispatchingLocked();
        }

        mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);

        // Notify when the task stack has changed, but only if visibilities changed (not just
        // focus). Also if there is an active root pinned task - we always want to notify it about
        // task stack changes, because its positioning may depend on it.
        if (mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause
                || (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) {
            mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
            mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
        }
    }

将mPausingActivity赋值为prev。

设置它不是在关闭或打开PIP的过程中。

判断prev是不是STOPPING状态,保存在wasStopping中。

并且将prev的状态设置为PAUSED,代表暂停状态完成。

如果prev已经是finishing,则调用它的completeFinishing完成finishing。

如果不是finishing状态,并且它有进程。这种情况下,又分了几种情况处理:

1、prev.deferRelaunchUntilPaused为true,代表延缓重启直到暂停完成,这里就调用它的relaunchActivityLocked方法,重新启动。

2、prev在设置PAUSED状态之前是STOPPING状态,在这里将它设置为STOPPING状态。

3、prev处于不可见状态,或者系统将睡眠或者关闭状态,清除掉prev的延缓客户端隐藏状态,并且将它添加到mTaskSupervisor.mStoppingActivities中,mTaskSupervisor.mStoppingActivities和prev的onStop周期执行相关。

接着调用prev.stopFreezingScreenLocked(true /force /),停止冻结屏幕。

这里就会将mPausingActivity = null。

如果参数resumeNext为true,代表需要恢复Activity执行。

如果mRootWindowContainer最顶端根任务不为null,并且系统不是将睡眠或关闭,这种情况下,调用mRootWindowContainer.resumeFocusedTasksTopActivities方法去执行Activity的恢复启动。这是第二次调用它的情况,详细参考这篇 Android 系统进程启动Activity方法说明

如果不符合上面这种情况,系统准备睡眠。如果顶层根任务没有可运行Activity,或者可运行Activity不等于prev,这个时候,也调用mRootWindowContainer.resumeFocusedTasksTopActivities()。

接下来,如果prev不为null,则恢复它的按键派发。

mRootWindowContainer.ensureActivitiesVisible方法来确保Activity的可见性。这个步骤里面会检测到上面的prev对象,不可见,因为它被遮挡了,所以会执行它的makeInvisible(),在该方法中,会设置它的可见性为false。并且如果它的状态为PAUSED,会将它添加到mTaskSupervisor.mStoppingActivities中,因为这块会影响到onStop生命周期的执行,这里要说一下。

如果Activity的可见性发生变化,或者TaskDisplayArea对象存在PinnedTask,这时发送任务栈改变的通知。

Activity恢复启动

如果暂停完成之后,待启动的Activity是新创建的Activity,在第二次执行Task类的resumeTopActivityInnerLocked方法时,启动的Activity是还没有绑定到进程上呢,即next.attachedToProcess()为false。详细见 Android 系统进程启动Activity方法说明。这个时候,它会调用ActivityTaskSupervisor类对象的startSpecificActivity方法,这里呢,咱们说简单的,进程已经存在的情况,看下它对应情况下的Activity生命周期执行。它调用的是ActivityTaskSupervisor类对象的realStartActivityLocked方法:

java 复制代码
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
	            ............
	            r.setProcess(proc);
	            ............
             	// Create activity launch transaction.
              final ClientTransaction clientTransaction = ClientTransaction.obtain(
                      proc.getThread(), r.appToken);

              final boolean isTransitionForward = r.isTransitionForward();
              clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                      System.identityHashCode(r), r.info,
                      // TODO: Have this take the merged configuration instead of separate global
                      // and override configs.
                      mergedConfiguration.getGlobalConfiguration(),
                      mergedConfiguration.getOverrideConfiguration(), r.compat,
                      r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                      r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                      r.takeOptions(), isTransitionForward,
                      proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                      r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                      r.getLaunchedFromBubble()));

              // Set desired final state.
              final ActivityLifecycleItem lifecycleItem;
              if (andResume) {
                  lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
              } else {
                  lifecycleItem = PauseActivityItem.obtain();
              }
              clientTransaction.setLifecycleStateRequest(lifecycleItem);

              // Schedule transaction.
              mService.getLifecycleManager().scheduleTransaction(clientTransaction);            

这里只将生命周期相关的方法贴出来,其他的省略了。

这里调用r.setProcess(proc)将Activity与进程绑定起来。其实就是将Activity类对象的app指向proc。

接着就和调度Pause事件比较相似了。

也是先构造一个ClientTransaction类对象clientTransaction。

这里它增加了一个LaunchActivityItem回调。

然后根据参数andResume,来将ResumeActivityItem还是PauseActivityItem设置到clientTransaction对象的mLifecycleStateRequest中。像我们这种情况,参数andResume为true,所以设置的是ResumeActivityItem类对象。

接着就是开始调度clientTransaction。

这些方法和前面暂停周期事件,是相似的,这里说下不一样的地方。

因为ClientTransaction带LaunchActivityItem回调,所以差异就在LaunchActivityItem回调。

1、它们先执行LaunchActivityItem的preExecute方法,然后执行ResumeActivityItem的preExecute方法。

2、再切换到应用主线程中执行LaunchActivityItem的execute方法,然后再执行LaunchActivityItem的postExecute。

3、执行ResumeActivityItem的execute方法,再继续执行ResumeActivityItem的postExecute方法。在执行ResumeActivityItem的execute方法之前,还会将它们之间的生命周期执行一遍。

先看一下,LaunchActivityItem类的preExecute方法,

java 复制代码
    @Override
    public void preExecute(ClientTransactionHandler client, IBinder token) {
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
                client, mAssistToken, mFixedRotationAdjustments, mShareableActivityToken,
                mLaunchedFromBubble);
        client.addLaunchingActivity(token, r);
        client.updateProcessState(mProcState, false);
        client.updatePendingConfiguration(mCurConfig);
        if (mActivityClientController != null) {
            ActivityClient.setActivityClientController(mActivityClientController);
        }
    }

在这里首先创建ActivityClientRecord 类对象r。

接着将它添加到ActivityThread对象的成员mLaunchingActivities中,client就是ActivityThread对象。

其他的就是更新进程相关信息和配置。

ResumeActivityItem类的preExecute方法也是更新进程状态,这里略过。

LaunchActivityItem的execute方法,

java 复制代码
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = client.getLaunchingActivity(token);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

这里首先将上面添加到mLaunchingActivities中的ActivityClientRecord 类对象取出来。

执行ActivityThread的handleLaunchActivity方法。它的方法如下:

java 复制代码
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
            ............
            final Activity a = performLaunchActivity(r, customIntent);
            ............
        	return a;
    }            

主要是执行performLaunchActivity方法:

java 复制代码
    /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
			............
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
			............
			Application app = r.packageInfo.makeApplication(false, mInstrumentation);	
			............
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ............
            r.setState(ON_CREATE);

            // updatePendingActivityConfiguration() reads from mActivities to update
            // ActivityClientRecord which runs in a different thread. Protect modifications to
            // mActivities to avoid race.
            synchronized (mResourcesManager) {
                mActivities.put(r.token, r);
            }
            ............

performLaunchActivity通过mInstrumentation.newActivity方法创建了Activity 对象activity 。

r.packageInfo.makeApplication方法创建了Application 类对象。

通过mInstrumentation.callActivityOnCreate方法调用Activity 对象的onCreate方法。

将ActivityClientRecord类对象状态设置为ON_CREATE,等会计算ON_RESUME之间的生命周期会使用。

并将ActivityClientRecord类对象放入mActivities中。

再看LaunchActivityItem的postExecute方法,

java 复制代码
    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        client.removeLaunchingActivity(token);
    }

将ActivityClientRecord类对象从mLaunchingActivities删除掉。

看ResumeActivityItem和当前Activity生命周期路径,因为ResumeActivityItem的getTargetState()为ON_RESUME,所以生命周期路径为[ON_START],所以会执行ActivityThread类对象的handleStartActivity方法,它里面会调用Activity的onStart方法。

再看看ResumeActivityItem的execute方法:

java 复制代码
    @Override
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

可以看到还是执行了ActivityThread类对象的handleResumeActivity方法。

java 复制代码
    @Override
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, String reason) {
            ............
           if (!performResumeActivity(r, finalStateRequest, reason)) {
	            return;
	        }
	        ............
	        mNewActivities = r;
	        Looper.myQueue().addIdleHandler(new Idler());

可见它执行了performResumeActivity方法,该方法里面调用了Activity的onResume方法。代表Activity恢复执行了。

将启动的ActivityClientRecord对象赋值给mNewActivities 。

最后向消息对列中添加一个Idler对象。

Activity停止

向消息对垒中添加的Idler对象消息,在主线程空闲时,会执行它的queueIdle(),看下它的执行。

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;
                final ActivityClient ac = ActivityClient.getInstance();
                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) {
                        ac.activityIdle(a.token, a.createdConfig, stopProfiling);
                        a.createdConfig = null;
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            if (stopProfiling) {
                mProfiler.stopProfiling();
            }
            applyPendingProcessState();
            return false;
        }
    }

它会在mNewActivities不为null的情况下,执行ActivityClient对象的activityIdle方法,它会通过Binder调用系统进程端ActivityClientController对象的activityIdle方法,

java 复制代码
    @Override
    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);
        }
    }

它主要调用mTaskSupervisor.activityIdleInternal方法,而activityIdleInternal方法里面会调用processStoppingAndFinishingActivities方法,

java 复制代码
    private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
            boolean processPausingActivities, String reason) {
        // Stop any activities that are scheduled to do so but have been waiting for the transition
        // animation to finish.
        ArrayList<ActivityRecord> readyToStopActivities = null;
        for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
            final ActivityRecord s = mStoppingActivities.get(i);
            final boolean animating = s.isAnimating(TRANSITION | PARENTS,
                    ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
                    || mService.getTransitionController().inTransition(s);
            ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
                    + "finishing=%s", s, s.nowVisible, animating, s.finishing);
            if (!animating || mService.mShuttingDown) {
                if (!processPausingActivities && s.isState(PAUSING)) {
                    // Defer processing pausing activities in this iteration and reschedule
                    // a delayed idle to reprocess it again
                    removeIdleTimeoutForActivity(launchedActivity);
                    scheduleIdleTimeout(launchedActivity);
                    continue;
                }

                ProtoLog.v(WM_DEBUG_STATES, "Ready to stop: %s", s);
                if (readyToStopActivities == null) {
                    readyToStopActivities = new ArrayList<>();
                }
                readyToStopActivities.add(s);

                mStoppingActivities.remove(i);
            }
        }

        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) {
                    // TODO(b/137329632): Wait for idle of the right activity, not just any.
                    r.destroyIfPossible(reason);
                } else {
                    r.stopIfPossible();
                }
            }
        }
        ............

可见这里就是从mTaskSupervisor的mStoppingActivities集合中取出来,然后调用ActivityRecord的stopIfPossible()方法。

而stopIfPossible()方法又通过构造StopActivityItem,组成ClientTransaction对象进行调度。而之前的暂停的Activity目前是onPause状态,所以就执行StopActivityItem的execute方法:

java 复制代码
    @Override
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
        client.handleStopActivity(r, mConfigChanges, pendingActions,
                true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

可见还是通过ActivityThread对象的handleStopActivity来执行Activity的onStop。

StopActivityItem的postExecute方法,还是在执行完停止之后,向系统进程发送应答。这样,会将系统端ActivityRecord对象的状态设置为STOPPED。

总结

这里过了一遍进程存在情况下的Activity启动的整体流程,主要是观察对应声明周期方法的执行。

可以看到,系统进程端会将对应周期类封装到ClientTransaction类对象进行调度,不同的周期类实现不同的preExecute、execute、postExecute方法。并且ClientTransaction还能添加回调,实现不同功能。

相关推荐
十六ᵛᵃᵉ9 分钟前
day3_Flink基础
android·java·flink
C_V_Better1 小时前
!!!谷歌停止开源安卓
android·开源
前行的小黑炭3 小时前
Kotlin的委托是什么?在看源码的时候不知道他的作用是什么,为什么使用,那么你看看这篇文章。
android·kotlin
前行的小黑炭3 小时前
Kotlin的扩展函数:给任何类添加你想要的功能,即使是自带类,第三方类。
android·kotlin
_一条咸鱼_3 小时前
Android Compose 框架的主题与样式模块之字体资源深度剖析(四十三)
android
程序猿John3 小时前
php调用deepseek接口api并流式输出
android·开发语言·php
技术蔡蔡4 小时前
Android闭源?假新闻?
android·开源·资讯
ufo00l4 小时前
Kotlin对Android整体编程有什么明显的改进,这几年自身有什么更新
android
洞见不一样的自己4 小时前
RecyclerView系列之二(下) ItemDecoration
android
用户1982333188404 小时前
一个冷门库J2V8的赋能之旅——深度绑定机制的实现
android·java·javascript