从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、 创建LaunchActivityItem与ActivityLifecycleItem
/** @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中创建的LaunchActivityItem与ActivityLifecycleItem加入到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的类:ActivityTransactionItem、ConfigurationChangeItem、LaunchActivityItem、WindowContextInfoChangeItem、WindowContextWindowRemovalItem、WindowStateTransactionItem
2.3、ActivityTransactionItem
抽象类,继承至ClientTransactionItem抽象类
直接继承至ActivityTransactionItem的类:ActivityConfigurationChangeItem、ActivityLifecycleItem、ActivityRelaunchItem、ActivityResultItem、EnterPipRequestedItem、MoveToDisplayItem、NewIntentItem、PipStateTransactionItem、RefreshCallbackItem、TopResumedActivityChangeItem、TransferSplashScreenViewStateItem、WindowStateTransactionItem
2.4、ActivityLifecycleItem
抽象类,继承至ActivityTransactionItem抽象类
DestroyActivityItem、PauseActivityItem、ResumeActivityItem、StartActivityItem、StopActivityItem、
2.5、WindowStateTransactionItem
抽象类,继承至ClientTransactionItem抽象类
WindowStateInsetsControlChangeItem、WindowStateResizeItem
3、ClientTransactionItem、ActivityTransactionItem与ActivityLifecycleItem之间的区别
ClientTransactionItem,所有的事务
ActivityTransactionItem,与Activity相关的事务,作用在一个已经存在的Activity上, 类中包含一个 IBinder类型mActivityToken字段,重写了getActivityToken()方法,并将mActivityToken字段进行返回
ActivityLifecycleItem, Activity生命周期状态迁移的特殊事务,类中定义了一系列生命周期状态, 重写了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