Activity生命周期调度

从Android9.0开始,引入ClientTransaction,将原本离散、多次的生命周期调度优化为事务机制进行,减少了跨进程Binder调用,连贯了生命周期调度

1、Activity启动流程

1.1、开始启动Activity
复制代码
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
    ......
       final RemoteException e = tryRealStartActivityInner(
                task, r, proc, activityClientController, andResume);
    ......
}
1.2、 创建LaunchActivityItemActivityLifecycleItem
复制代码
/** @return {@link RemoteException} if the app process failed to handle the activity start. */
@Nullable
private RemoteException tryRealStartActivityInner(
        @NonNull Task task,
        @NonNull ActivityRecord r,
        @NonNull WindowProcessController proc,
        @Nullable IActivityClientController activityClientController,
        boolean andResume) {
    ......
    // Create activity launch transaction.
    final boolean isTransitionForward = r.isTransitionForward();
    final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
    final int deviceId = getDeviceIdForDisplayId(r.getDisplayId());
    final LaunchActivityItem launchActivityItem = new LaunchActivityItem(r.token,
            r.intent, System.identityHashCode(r), r.info,
            procConfig, overrideConfig, deviceId,
            r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
            proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
            results, newIntents, r.takeSceneTransitionInfo(), isTransitionForward,
            proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
            r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken,
            r.initialCallerInfoAccessToken, activityWindowInfo, r.getDisplayId());

    // Set desired final state.
    final ActivityLifecycleItem lifecycleItem;
    if (andResume) {
        lifecycleItem = new ResumeActivityItem(r.token, isTransitionForward,
                r.shouldSendCompatFakeFocus());
    } else if (r.isVisibleRequested()) {
        lifecycleItem = new PauseActivityItem(r.token);
    } else {
        lifecycleItem = new StopActivityItem(r.token);
    }

    // Schedule transaction.
    if (shouldDispatchLaunchActivityItemIndependently(r.info.packageName, r.getUid())) {
        // LaunchActivityItem has @UnsupportedAppUsage usages.
        // Guard with targetSDK on Android 15+.
        // To not bundle the transaction, dispatch the pending before schedule new
        // transaction.
        mService.getLifecycleManager().dispatchPendingTransaction(proc.getThread());
    }
    final boolean isSuccessful = mService.getLifecycleManager().scheduleTransactionItems(
            proc.getThread(),
            // Immediately dispatch the transaction, so that if it fails, the server can
            // restart the process and retry now.
            true /* shouldDispatchImmediately */,
            launchActivityItem, lifecycleItem);
    if (!isSuccessful) {
        return new DeadObjectException("Failed to dispatch the ClientTransaction to dead"
                + " process. See earlier log for more details.");
    }

    
    ......
}
1.3、获取或者创建ClientTransaction,并将1.2中创建的LaunchActivityItemActivityLifecycleItem加入到ClientTransaction
复制代码
/**
 * Schedules a transaction with the given items, delivery to client application, which may be
 * queued to dispatched later.
 *
 * @return {@code false} if the transaction was dispatched immediately, but failed because of
 *         {@link RemoteException}. If the transaction is queued, any failure will be ignored.
 * @see ClientTransactionItem
 */
boolean scheduleTransactionItems(@NonNull IApplicationThread client,
        @NonNull ClientTransactionItem... items) {
    return scheduleTransactionItems(client, false /* shouldDispatchImmediately */, items);
}

/**
 * Schedules a transaction with the given items, delivery to client application, which may be
 * queued to dispatched later.
 *
 * @param shouldDispatchImmediately whether or not to dispatch the transaction immediately. This
 *                                  should only be {@code true} when it is important to know the
 *                                  result of dispatching immediately. For example, when cold
 *                                  launches an app, the server needs to know if the transaction
 *                                  is dispatched successfully, and may restart the process if
 *                                  not.
 * @return {@code false} if the transaction was dispatched immediately, but failed because of
 *         {@link RemoteException}. If the transaction is queued, any failure will be ignored.
 * @see ClientTransactionItem
 */
boolean scheduleTransactionItems(@NonNull IApplicationThread client,
        boolean shouldDispatchImmediately,
        @NonNull ClientTransactionItem... items) {
    // Wait until RootWindowContainer#performSurfacePlacementNoTrace to dispatch all pending
    // transactions at once.
    final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);

    final int size = items.length;
    for (int i = 0; i < size; i++) {
        clientTransaction.addTransactionItem(items[i]);
    }

    return onClientTransactionItemScheduled(clientTransaction, shouldDispatchImmediately);
}
1.4、执行ClientTransaction.schedule()
复制代码
 /**
  * Must only be called with WM lock.
  * If the transaction should not be queued, it will be dispatched immediately.
  *
  * @return {@code false} if the transaction was dispatched immediately, but failed because of
  *         {@link RemoteException}.
  */
private boolean onClientTransactionItemScheduled(
        @NonNull ClientTransaction clientTransaction,
        boolean shouldDispatchImmediately) {
    if (shouldDispatchImmediately || shouldDispatchPendingTransactionsImmediately()) {
        // Dispatch the pending transaction immediately.
        mPendingTransactions.remove(clientTransaction.getClient().asBinder());
        return scheduleTransaction(clientTransaction);
    }
    return true;
}

/**
 * Schedules a transaction, which may consist of multiple callbacks and a lifecycle request.
 * @param transaction A sequence of client transaction items.
 * @return {@code false} if the transaction failed because of {@link RemoteException}.
 * @see ClientTransaction
 */
@VisibleForTesting
boolean scheduleTransaction(@NonNull ClientTransaction transaction) {
    final RemoteException e = transaction.schedule();
    if (e != null) {
        final WindowProcessController wpc = mWms.mAtmService.getProcessController(
                transaction.getClient());
        Slog.w(TAG, "Failed to deliver transaction for " + wpc + "\ntransaction=" + this, e);
        return false;
    }
    return true;
}
1.5、通过IApplicationThreadBinder代理从system_server进程回调至App进程
复制代码
/**
 * 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.
 *
 * @return {@link RemoteException} if the transaction failed.
 */
@Nullable
public RemoteException schedule() {
    try {
        mClient.scheduleTransaction(this);
        return null;
    } catch (RemoteException e) {
        return e;
    }
}

@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}
1.6、向主线程的消息队列投递EXECUTE_TRANSACTION类型消息
复制代码
// Schedule phase related logic and handlers.

/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

@Override
public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    long debugStoreId = -1;
    // By default, log all long messages when the debug store is enabled,
    // unless this is overridden for certain message types, for which we have
    // more granular debug store logging.
    boolean shouldLogLongMessage = DEBUG_STORE_ENABLED;
    final long messageStartUptimeMs = SystemClock.uptimeMillis();
    switch (msg.what) {
        case BIND_APPLICATION:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
            if (DEBUG_STORE_ENABLED) {
                debugStoreId =
                        DebugStore.recordBindApplication();
            }
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            if (DEBUG_STORE_ENABLED) {
                DebugStore.recordEventEnd(debugStoreId);
            }
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        ......
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            final ClientTransactionListenerController controller =
                    ClientTransactionListenerController.getInstance();
            controller.onClientTransactionStarted();
            try {
                mTransactionExecutor.execute(transaction);
            } finally {
                controller.onClientTransactionFinished();
            }
            break;
        ......
    }
}
1.7、在TransactionExecutor中执行在system_server进程添加的ClientTransactionItem(包含执行动作与目标状态)
复制代码
/**
 * 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(@NonNull ClientTransaction transaction) {
    if (DEBUG_RESOLVER) {
        Slog.d(TAG, tId(transaction) + "Start resolving transaction");
        Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
    }

    Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "clientTransactionExecuted");
    try {
        executeTransactionItems(transaction);
    } catch (Exception e) {
        Slog.e(TAG, "Failed to execute the transaction: "
                + transactionToString(transaction, mTransactionHandler));
        throw e;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
    }

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

/** Cycles through all transaction items and execute them at proper times. */
@VisibleForTesting
public void executeTransactionItems(@NonNull ClientTransaction transaction) {
    final List<ClientTransactionItem> items = transaction.getTransactionItems();
    final int size = items.size();
    for (int i = 0; i < size; i++) {
        final ClientTransactionItem item = items.get(i);
        if (item.isActivityLifecycleItem()) {
            executeLifecycleItem(transaction, (ActivityLifecycleItem) item);
        } else {
            executeNonLifecycleItem(transaction, item,
                    shouldExcludeLastLifecycleState(items, i));
        }
    }
}
1.8、通过executeNonLifecycleItem(...)方法,执行ClientTransactionItem动作
复制代码
private void executeNonLifecycleItem(@NonNull ClientTransaction transaction,
        @NonNull ClientTransactionItem item, boolean shouldExcludeLastLifecycleState) {
    final IBinder token = item.getActivityToken();
    ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    if (token != null && r == null
            && mTransactionHandler.getActivitiesToBeDestroyed().containsKey(token)) {
        // 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, "Skip pre-destroyed transaction item:\n" + item);
        return;
    }

    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
    final int postExecutionState = item.getPostExecutionState();

    if (item.shouldHaveDefinedPreExecutionState()) {
        final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                postExecutionState);
        if (closestPreExecutionState != UNDEFINED) {
            cycleToPath(r, closestPreExecutionState, transaction);
        }
    }

    item.execute(mTransactionHandler, mPendingActions);

    item.postExecute(mTransactionHandler, mPendingActions);
    if (r == null) {
        // Launch activity request will create an activity record.
        r = mTransactionHandler.getActivityClient(token);
    }

    if (postExecutionState != UNDEFINED && r != null) {
        cycleToPath(r, postExecutionState, shouldExcludeLastLifecycleState, transaction);
    }
}
1.9、执行实际的动作ClientTransactionItem
复制代码
@Override
public void execute(@NonNull ClientTransactionHandler client,
        @NonNull PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    final ActivityClientRecord r = new ActivityClientRecord(mActivityToken, mIntent, mIdent,
            mInfo, mOverrideConfig, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mSceneTransitionInfo, mIsForward,
            mProfilerInfo, client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
            mTaskFragmentToken, mInitialCallerInfoAccessToken, mActivityWindowInfo);
    client.handleLaunchActivity(r, pendingActions, mDeviceId, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
1.10、通过executeLifecycleItem(...)方法,从当前状态执行至目标状态
复制代码
private void executeLifecycleItem(@NonNull ClientTransaction transaction,
        @NonNull ActivityLifecycleItem lifecycleItem) {
    final IBinder token = lifecycleItem.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) {
        if (mTransactionHandler.getActivitiesToBeDestroyed().get(token) == lifecycleItem) {
            // Always cleanup for destroy item.
            lifecycleItem.postExecute(mTransactionHandler, mPendingActions);
        }
        // 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, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, mPendingActions);
}
1.11、先通过cycleToPath(...)方法,计算出从当前状态到目标状态所需要补全的中间状态,然后根据中间状态依次执行对应的方法
复制代码
/**
 * Transition the client between states with an option not to perform the last hop in the
 * sequence. This is used when resolving lifecycle state request, when the last transition must
 * be performed with some specific parameters.
 */
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);
}

/** Transition the client through previously initialized state sequence. */
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,
                        Context.DEVICE_ID_INVALID, null /* customIntent */);
                break;
            case ON_START:
                mTransactionHandler.handleStartActivity(r, mPendingActions,
                        null /* sceneTransitionInfo */);
                break;
            case ON_RESUME:
                mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                        r.isForward, false /* shouldSendCompatFakeFocus */,
                        "LIFECYCLER_RESUME_ACTIVITY");
                break;
            case ON_PAUSE:
                mTransactionHandler.handlePauseActivity(r, false /* finished */,
                        false /* userLeaving */,
                        false /* autoEnteringPip */, mPendingActions,
                        "LIFECYCLER_PAUSE_ACTIVITY");
                break;
            case ON_STOP:
                mTransactionHandler.handleStopActivity(r,
                        mPendingActions, false /* finalStateRequest */,
                        "LIFECYCLER_STOP_ACTIVITY");
                break;
            case ON_DESTROY:
                mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                        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);
        }
    }
}
1.12、执行实际的目标状态ActivityLifecycleItem
复制代码
@Override
public void execute(@NonNull ClientTransactionHandler client, @NonNull ActivityClientRecord r,
        @NonNull PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
    client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
            mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

2、ClientTransaction、ClientTransactionItem、ActivityTransactionItem 与 ActivityLifecycleItem

2.1、ClientTransaction

在ClientTransaction的mTransactionItems中, 持有App进程需要执行的ClientTransactionItem与目标状态ActivityLifecycleItem

复制代码
/**
 * A container that holds a sequence of messages, which may be sent to a client.
 * This includes a list of callbacks and a final lifecycle state.
 *
 * @see com.android.server.wm.ClientLifecycleManager
 * @see ClientTransactionItem
 * @see ActivityLifecycleItem
 * @hide
 */
public class ClientTransaction implements Parcelable {

    /**
     * List of transaction items that should be executed in order. Including both
     * {@link ActivityLifecycleItem} and other {@link ClientTransactionItem}.
     */
    @NonNull
    private final List<ClientTransactionItem> mTransactionItems = new ArrayList<>();

    /** @deprecated use {@link #getTransactionItems} instead. */
    @Nullable
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
            trackingBug = 324203798,
            publicAlternatives = "Use {@code #getTransactionItems()}")
    @Deprecated
    private List<ClientTransactionItem> mActivityCallbacks;

    /**
     * Final lifecycle state in which the client activity should be after the transaction is
     * executed.
     */
    // TODO(b/324203798): cleanup after remove UnsupportedAppUsage
    @Nullable
    private ActivityLifecycleItem mLifecycleStateRequest;

    /** Only kept for unsupportedAppUsage {@link #getActivityToken()}. Must not be used. */
    // TODO(b/324203798): cleanup after remove UnsupportedAppUsage
    @Nullable
    private IBinder mActivityToken;

    /**
     * The target client.
     * <p>
     * This field is null only if the object is:
     * - Read from a Parcel on the client side.
     * - Constructed for testing purposes.
     * <p>
     * When created directly on the server, this field represents the server's connection to the
     * target client's application thread. It is omitted during parceling and not sent to the
     * client. On the client side, this field becomes unnecessary.
     */
    @Nullable
    private final IApplicationThread mClient;
    ......
}
2.2、ClientTransactionItem

抽象类,实现了BaseClientRequest与Parcelable接口

直接继承至ClientTransactionItem的类:ActivityTransactionItemConfigurationChangeItemLaunchActivityItemWindowContextInfoChangeItemWindowContextWindowRemovalItemWindowStateTransactionItem

2.3、ActivityTransactionItem

抽象类,继承至ClientTransactionItem抽象类

直接继承至ActivityTransactionItem的类:ActivityConfigurationChangeItemActivityLifecycleItemActivityRelaunchItemActivityResultItemEnterPipRequestedItemMoveToDisplayItemNewIntentItemPipStateTransactionItemRefreshCallbackItemTopResumedActivityChangeItemTransferSplashScreenViewStateItemWindowStateTransactionItem

2.4、ActivityLifecycleItem

抽象类,继承至ActivityTransactionItem抽象类

DestroyActivityItemPauseActivityItemResumeActivityItemStartActivityItemStopActivityItem

2.5、WindowStateTransactionItem

抽象类,继承至ClientTransactionItem抽象类

WindowStateInsetsControlChangeItemWindowStateResizeItem

3、ClientTransactionItem、ActivityTransactionItem与ActivityLifecycleItem之间的区别

ClientTransactionItem,所有的事务

ActivityTransactionItem,与Activity相关的事务,作用在一个已经存在的Activity上, 类中包含一个 IBinder类型mActivityToken字段,重写了getActivityToken()方法,并将mActivityToken字段进行返回

ActivityLifecycleItemActivity生命周期状态迁移的特殊事务,类中定义了一系列生命周期状态, 重写了isActivityLifecycleItem()方法,并返回true。另外,新增了一个getTargetState()抽象方法,用于子类覆盖重写,其返回值表示最终需要迁移到的目标状态

复制代码
@IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
        UNDEFINED,
        PRE_ON_CREATE,
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_RESTART
})
@Retention(RetentionPolicy.SOURCE)
public @interface LifecycleState{}
public static final int UNDEFINED = -1;
public static final int PRE_ON_CREATE = 0;
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;

4、system_server进程执行链路

ActivityTaskSupervisor ->ClientTransactionManager ->ClientTransaction --->ApplicationThread

5、App进程执行链路

ApplicationThread -> ActivityThread(ClientTransactionHandler) -> TransactionExecutor -> ClientTransactionItem -> ActivityThread

相关推荐
Fate_I_C2 小时前
Android Navigation组件核心问题深度解析
android·kotlin·navigation
撩得Android一次心动2 小时前
Android Room 数据库详解【使用篇】
android·数据库·room·jetpack
恋猫de小郭2 小时前
Jetpack Compose 1.11 正式版发布,下一代的全新控件和样式 API,你必须知道
android·前端·flutter
Kapaseker2 小时前
Kotlin 的 init 到底咋回事儿?
android·kotlin
黄林晴2 小时前
Compose 四月稳定版来袭,测试、触控、预览工具全线革新
android
克里斯蒂亚诺更新2 小时前
uniapp适配H5和Android-apk实现获取当前位置经纬度并调用接口
android·前端·uni-app
咚咚王者3 小时前
MySQL 导出脚本
android·mysql·adb
Fate_I_C3 小时前
Android Navigation的使用说明
android·kotlin·navigation
JJay.3 小时前
高通 GAIA v1/v2/v3 共存时,Android 端该怎么做协议分层
android