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

相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui