ClientTransaction发送过程
总结
简化版
具体步骤
服务端
客户端发送信息之前:preExecute
客户端处理:execute postExecute cycleToPath
cycleToPath方法
总结:形成一个ClientTransaction,然后ClientLifecycleManager的scheduleTransaction方法将其发送到客户端,ClientTransaction在客户端发送消息到主线程之前执行preExecute方法,发送到主线程后,TransactionExecutor调用execute执行该ClientTransaction。TransactionExecutor会用到类型为ClientTransactionHandler(ActivityThread实现该类,用于获取客户端activity状态)和TransactionExecutorHelper (用于得到cyclePath)的成员进行辅助执行。
简短总结:ClientLifecycleManager发送ClientTransaction到TransactionExecutor执行。成员ClientTransactionHandler和TransactionExecutorHelper 帮助TransactionExecutor执行。
–——————-
代码跟踪
**
* A container that holds a sequence of messages, which may be sent to a client.
* This includes a list of callbacks and a .
*
* @see com.android.server.am.ClientLifecycleManager
* @see ClientTransactionItem
* @see ActivityLifecycleItem
* @hide
*/
public class ClientTransaction implements Parcelable, ObjectPoolItem {
/** A list of individual callbacks to a client. */
@UnsupportedAppUsage
private List<ClientTransactionItem> mActivityCallbacks;
/**
* Final lifecycle state in which the client activity should be after the transaction is
* executed.
*/
private ActivityLifecycleItem mLifecycleStateRequest;
/** Target client. */
private IApplicationThread mClient;
/** Target client activity. Might be null if the entire transaction is targeting an app. */
private IBinder mActivityToken;
}
向客户端传输信息:包含信息类型ActivityLifecycleItem( 生命周期状态请求final lifecycle state)和客户端要执行的callback集合(ClientTransactionItem 集合),还有activityToken
mClient为客户端
mActivityToken:目标activity的token( activityRecord的appToken属性),如果clientTranscation是作用于应用,则为null。
ActivityLifecycleItem:生命周期状态请求
ActivityLifecycleItem 继承ActivityTransactionItem,ActivityTransactionItem继承ClientTransactionItem
StartActivityItem:继承ActivityLifecycleItem
ResumeActivityItem:继承ActivityLifecycleItem
PauseActivityItem:继承ActivityLifecycleItem
StopActivityItem:继承ActivityLifecycleItem
DestroyActivityItem:继承ActivityLifecycleItem
ClientTransactionItem:callback
LaunchActivityItem:继承ClientTransactionItem
ActivityRelaunchItem:ActivityTransactionItem
NewIntentItem:ActivityTransactionItem
ActivityResultItem:ActivityTransactionItem
TopResumedActivityChangeItem:ActivityTransactionItem
它门都继承ActivityTransactionItem抽象类,而ActivityTransactionItem实现ClientTransactionItem接口。ActivityTransactionItem相当于一个辅助类,实现ClientTransactionItem的一些方法,具体类只要重写自己感兴趣的方法即可。
getPostExecutionState返回希望客户端执行该ClientTransactionItem后应该进入的状态。
public abstract class ClientTransactionItem implements BaseClientRequest, Parcelable {
/** Get the state that must follow this callback. */
@LifecycleState
public int getPostExecutionState() {
return UNDEFINED;
}
// Parcelable
@Override
public int describeContents() {
return 0;
}
}
ublic interface BaseClientRequest extends ObjectPoolItem {
/**
* Prepare the client request before scheduling.
* An example of this might be informing about pending updates for some values.
*
* @param client Target client handler.
* @param token Target activity token.
*/
default void preExecute(ClientTransactionHandler client, IBinder token) {
}
/**
* Execute the request.
* @param client Target client handler.
* @param token Target activity token.
* @param pendingActions Container that may have data pending to be used.
*/
void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions);
/**
* Perform all actions that need to happen after execution, e.g. report the result to server.
* @param client Target client handler.
* @param token Target activity token.
* @param pendingActions Container that may have data pending to be used.
*/
default void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
}
}
继承ActivityTransactionItem必须preExecute、execute和postExecute方法(ActivityTransactionItem中没有实现该方法)。preExecute为在客户端发送消息给主线程之前执行,而execute为主线程的消息队列中取出后执行,postExecute一般为通知ATMS。
ClientLifecycleManager
ATMS的成员mLifecycleManager,用户向客户端发送ClientTransaction。
private final ClientLifecycleManager mLifecycleManager;
描述
/**
* Class that is able to combine multiple client lifecycle transition requests and/or callbacks,
* and execute them as a single transaction
ClientLifecycleManager调用scheduleTransaction发送ClientTransaction。根据用户填入的参数情况,则具体情形有以下三种
-
参数为ClientTransaction
则直接调用scheduleTransaction方法发送
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(); } }
-
参数为ActivityLifecycleItem
也是调用scheduleTransaction方法发送,但是发送之前会先调用transactionWithState将其包装为ClientTransaction
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) throws RemoteException { final ClientTransaction clientTransaction = transactionWithState(client, activityToken, stateRequest); scheduleTransaction(clientTransaction); } private static ClientTransaction transactionWithState(@NonNull IApplicationThread client, @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) { final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken); clientTransaction.setLifecycleStateRequest(stateRequest); return clientTransaction; }
-
参数为ClientTransactionItem
也是调用scheduleTransaction方法发送,但是发送之前会先调用transactionWithCallback将其包装为ClientTransaction
一般用户是填入ClientTransactionItem,而ClientLifecycleMananger对于生命周期状态请求和回调提供对于的方法进行包装成为ClientTransactionItem。
/**
* Schedule a single callback delivery to client activity.
* @param client Target client.
* @param activityToken Target activity token.
* @param callback A request to deliver a callback.
* @throws RemoteException
*
* @see ClientTransactionItem
*/
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
@NonNull ClientTransactionItem callback) throws RemoteException {
final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken,
callback);
scheduleTransaction(clientTransaction);
}
/**
* @return A new instance of {@link ClientTransaction} with a single lifecycle state request.
*
* @see ClientTransaction
* @see ClientTransactionItem
*/
/**
* @return A new instance of {@link ClientTransaction} with a single callback invocation.
*
* @see ClientTransaction
* @see ClientTransactionItem
*/
private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client,
IBinder activityToken, @NonNull ClientTransactionItem callback) {
final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
clientTransaction.addCallback(callback);
return clientTransaction;
}
PauseActivityItem
应用起来之前先pause上一个应用,pauseImmediately为false
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately))
/** Obtain an instance initialized with provided params. */
public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges,
boolean dontReport) {
PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
if (instance == null) {
instance = new PauseActivityItem();
}
instance.mFinished = finished;
instance.mUserLeaving = userLeaving;
instance.mConfigChanges = configChanges;
instance.mDontReport = dontReport;
return instance;
}
包装为ClientTransaction 并发送
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
@NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
stateRequest);
scheduleTransaction(clientTransaction);
}
private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
@NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
clientTransaction.setLifecycleStateRequest(stateRequest);
return clientTransaction;
}
/** Obtain an instance initialized with provided params. */
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}
/**
* Set the lifecycle state in which the client should be after executing the transaction.
* @param stateRequest A lifecycle request initialized with right parameters.
*/
public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
mLifecycleStateRequest = stateRequest;
}
```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();
}
}
```java
/**
* Schedule the transaction after it was initialized. It will be send to client and all its
* individual parts will be applied in the following sequence:
* 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
* that needs to be done before actually scheduling the transaction for callbacks and
* lifecycle state request.
* 2. The transaction message is scheduled.
* 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
* all callbacks and necessary lifecycle transitions.
*/
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
来到客户端
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
this的类型为ClientTransactionHandler ,ActivityThread继承了该类,这里其实是ActivityThread.ClientTransactionHandler 定义了ClientTransaction和ClientThransactionItem所能执行的操作,其实是一个工具接口,其作为TransactionExecutor的成员,TransactionExecutor在执行ClientTransaction的时候通过它可以获取客户端的一些信息。
/**
* Defines operations that a {@link android.app.servertransaction.ClientTransaction} or its items
* can perform on client.
* @hide
*/
public abstract class ClientTransactionHandler {
mTransactionHandler
消息发送到主线程前执行preExecute
/**
* Do what needs to be done while the transaction is being scheduled on the client side.
* @param clientTransactionHandler Handler on the client side that will executed all operations
* requested by transaction items.
*/
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);
}
}
这里执行PauseActivityItem的preExecute,PauseActivityItem没有重写该方法,该方法是一个空方法。
发送消息EXECUTE_TRANSACTION
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) {
Slog.v(TAG,
"SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
}
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
//这里-------
mH.sendMessage(msg);
}
处理消息
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 是ActivityThread的成员,其功能就是解析ClientTransaction,然后调用ClientTransaction内部ClientTransactionItem的execute方法
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
/**
* Resolve transaction.
* First all callbacks will be executed in the order they appear in the list. If a callback
* requires a certain pre- or post-execution state, the client will be transitioned accordingly.
* Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
* either remain in the initial state, or last state needed by a callback.
*/
public void execute(ClientTransaction transaction) {
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");
}
执行callback,pause的ClientTransaction没有callback,
/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
// No callbacks to execute, return early.
return;
}
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
// In case when post-execution state of the last callback matches the final state requested
// for the activity in this transaction, we won't do the last transition here and do it when
// moving to final state instead (because it may contain additional parameters from server).
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
: UNDEFINED;
// Index of the last callback that requests some post-execution state.
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
//避免选择path过长,先run到最接近希望状态的状态,然后后面再从该状态run到目标状态
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
item.execute(mTransactionHandler, token, );
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
}
if (postExecutionState != UNDEFINED && r != null) {
// Skip the very last transition and perform it by explicit state request instead.
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
/** Transition the client between states. */
@VisibleForTesting
public void cycleToPath(ActivityClientRecord r, int finish, ClientTransaction transaction) {
cycleToPath(r, finish, false /* excludeLastState */, transaction);
}
/**
* Pick a state that goes before provided post-execution state and would require the least
* lifecycle transitions to get to.
* It will also make sure to try avoiding a path with activity destruction and relaunch if
* possible.
* @param r An activity that we're trying to resolve the transition for.
* @param postExecutionState Post execution state to compute for.
* @return One of states that precede the provided post-execution state, or
* {@link ActivityLifecycleItem#UNDEFINED} if there is not path.
*/
@VisibleForTesting
public int getClosestPreExecutionState(ActivityClientRecord r,
int postExecutionState) {
switch (postExecutionState) {
case UNDEFINED:
return UNDEFINED;
case ON_RESUME:
return getClosestOfStates(r, ON_RESUME_PRE_EXCUTION_STATES);
default:
throw new UnsupportedOperationException("Pre-execution states for state: "
+ postExecutionState + " is not supported.");
}
}
private static final int[] ON_RESUME_PRE_EXCUTION_STATES = new int[] { ON_START, ON_PAUSE };
/**
* Pick a state that would require the least lifecycle transitions to get to.
* It will also make sure to try avoiding a path with activity destruction and relaunch if
* possible.
* @param r An activity that we're trying to resolve the transition for.
* @param finalStates An array of valid final states.
* @return One of the provided final states, or {@link ActivityLifecycleItem#UNDEFINED} if none
* were provided or there is not path.
*/
@VisibleForTesting
public int getClosestOfStates(ActivityClientRecord r, int[] finalStates) {
if (finalStates == null || finalStates.length == 0) {
return UNDEFINED;
}
final int currentState = r.getLifecycleState();
int closestState = UNDEFINED;
for (int i = 0, shortestPath = Integer.MAX_VALUE, pathLength; i < finalStates.length; i++) {
getLifecyclePath(currentState, finalStates[i], false /* excludeLastState */);
pathLength = mLifecycleSequence.size();
if (pathInvolvesDestruction(mLifecycleSequence)) {
pathLength += DESTRUCTION_PENALTY;
}
if (shortestPath > pathLength) {
shortestPath = pathLength;
closestState = finalStates[i];
}
}
return closestState;
}
生命周期回调,cycleToPath排除最后一个回调
/** Transition to the final state if requested by the transaction. */
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);
}
@Override
public ActivityClientRecord getActivityClient(IBinder token) {
return mActivities.get(token);
}
getTargetState返回请求最终状态,PauseActivityItem的为ON_PAUSE ,值为4
@Override
public int getTargetState() {
return ON_PAUSE;
}
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;
cycleToPath 将生命周期变为路径,即如果开始状态为on_resume 这次请求的的目标状态为on_stop,则path 为(on_pause,on_stop), 生命周期的顺序为PRE_ON_CREATE→ON_CREATE →ON_START →ON_RESUME →ON_PAUSE →ON_STOP →ON_DESTROY →ON_RESTART
下面是不同的cycle对应的path,其中x为起始状态,y为请求的终点状态
-
错误状态
- x和y都不能为UNDEFINED
- x和y不能为ON_RESTART ,因为on_restart不是一个稳定的状态,其只是一个过渡状态。这种情况会报错
- y为pre_on_create,而x不是pre_on_create,则报错,因为pre_on_create是第一个状态,其它状态不能到达它。
-
当终点状态大于起始状态
ON_START :ON_STOP ON_STOP
x:y (y≥x) x+1,x+2,x+3,…,y
-
终点状态小于起始状态
ON_PAUSE :ON_RESUME ON_RESUME
x:y (x≥on_stop,y≤on_start,x≥y) x+1,x+2,…on_stop,on_restart,on_start, on_start+1,…y (先到stop,再重start开始到y)
其它情况:on_start+1,on_start+2,…on_destory,on_create,on_create+1,…y(先到destory,再从create开始)
综上就是下面这个图
destory到start和start之下的节点要走经过restart的这条路径
/**
* 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.
*/
//finsih不是表示finish状态,而是表示请求的目标状态
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);
}
ActivityClientRecord 的getLifecycleState方法,返回客户端状态,就行前面所说的那几种状态(on_create、on_puase等)
/** Get the current lifecycle state. */
public int getLifecycleState() {
return mLifecycleState;
}
mHelper 为TransactionExecutor的TransactionExecutorHelper 类型成员
private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
/**
* Calculate the path through main lifecycle states for an activity and fill
* @link #mLifecycleSequence} with values starting with the state that follows the initial
* state.
* <p>NOTE: The returned value is used internally in this class and is not a copy. It's contents
* may change after calling other methods of this class.</p>
*/
@VisibleForTesting
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
if (start == UNDEFINED || finish == UNDEFINED) {
throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
}
if (start == ON_RESTART || finish == ON_RESTART) {
throw new IllegalArgumentException(
"Can't start or finish in intermittent RESTART state");
}
if (finish == PRE_ON_CREATE && start != finish) {
throw new IllegalArgumentException("Can only start in pre-onCreate state");
}
mLifecycleSequence.clear();
if (finish >= start) {
if (start == ON_START && finish == ON_STOP) {
// A case when we from start to stop state soon, we don't need to go
// through the resumed, paused state.
mLifecycleSequence.add(ON_STOP);
} else {
// just go there
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
} else { // finish < start, can't just cycle down
if (start == ON_PAUSE && finish == ON_RESUME) {
// Special case when we can just directly go to resumed state.
mLifecycleSequence.add(ON_RESUME);
} else if (start <= ON_STOP && finish >= ON_START) {
// Restart and go to required state.
// Go to stopped state first.
for (int i = start + 1; i <= ON_STOP; i++) {
mLifecycleSequence.add(i);
}
// Restart
mLifecycleSequence.add(ON_RESTART);
// Go to required state
for (int i = ON_START; i <= finish; i++) {
mLifecycleSequence.add(i);
}
} else {
// Relaunch and go to required state
// Go to destroyed state first.
for (int i = start + 1; i <= ON_DESTROY; i++) {
mLifecycleSequence.add(i);
}
// Go to required state
for (int i = ON_CREATE; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
}
// Remove last transition in case we want to perform it with some specific params.
if (excludeLastState && mLifecycleSequence.size() != 0) {
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
return mLifecycleSequence;
}
excludeLastState表示是否移除mLifecycleSequence的最后一个元素
performLifecycleSequence(r, path, transaction);执行path中的各个状态,对于resume到pause而言path为空(因为excludeLastState为true)
/** 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,
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);
}
}
}
Pause
先发TopResumedActivityChangeItem
然后再发PauseActivityItem
1 TopResumedActivityChangeItem
是为了支持multi-window 模式的,multi window引入了multi-resume的概念。
To help support the multi-resume feature, there’s a new lifecycle callback, [onTopResumedActivityChanged()](https://developer.android.com/reference/android/app/Activity#onTopResumedActivityChanged(boolean))
.
postExecute
resume被pause时,onTo为false
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
TopResumedActivityChangeItem.obtain(onTop));
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "topResumedActivityChangeItem");
client.handleTopResumedActivityChanged(r, mOnTop, "topResumedActivityChangeItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mOnTop) {
return;
}
// The loss of top resumed state can always be reported immediately in postExecute
// because only three cases are possible:
// 1. Activity is in RESUMED state now and it just handled the callback in #execute().
// 2. Activity wasn't RESUMED yet, which means that it didn't receive the top state yet.
// 3. Activity is PAUSED or in other lifecycle state after PAUSED. In this case top resumed
// state loss was already called right before pausing.
ActivityClient.getInstance().activityTopResumedStateLost();
}
1.1 execute
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "topResumedActivityChangeItem");
client.handleTopResumedActivityChanged(r, mOnTop, "topResumedActivityChangeItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
handleTopResumedActivityChanged—>reportTopResumedActivityChanged—>performTopResumedActivityChanged
@Override
public void handleTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
String reason) {
if (DEBUG_ORDER) {
Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
}
if (r.isTopResumedActivity == onTop) {
if (!Build.IS_DEBUGGABLE) {
Slog.w(TAG, "Activity top position already set to onTop=" + onTop);
return;
}
// TODO(b/197484331): Remove this short-term workaround while fixing the binder failure.
Slog.e(TAG, "Activity top position already set to onTop=" + onTop);
}
r.isTopResumedActivity = onTop;
if (r.getLifecycleState() == ON_RESUME) {
reportTopResumedActivityChanged(r, onTop, "topStateChangedWhenResumed");
} else {
if (DEBUG_ORDER) {
Slog.d(TAG, "Won't deliver top position change in state=" + r.getLifecycleState());
}
}
}
reportTopResumedActivityChanged:主要是打印日志
/**
* Call {@link Activity#onTopResumedActivityChanged(boolean)} if its top resumed state changed
* since the last report.
*/
private void reportTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
String reason) {
if (r.lastReportedTopResumedState != onTop) {
原来是top resuem,目标状态不是了,
r.lastReportedTopResumedState = onTop;
r.activity.performTopResumedActivityChanged(onTop, reason);
}
}
// This holds the value last sent to the activity. This is needed, because an update from
// server may come at random time, but we always need to report changes between ON_RESUME
// and ON_PAUSE to the app.
boolean lastReportedTopResumedState;
final void performTopResumedActivityChanged(boolean isTopResumedActivity, String reason) {
onTopResumedActivityChanged(isTopResumedActivity);
if (isTopResumedActivity) {
EventLogTags.writeWmOnTopResumedGainedCalled(mIdent, getComponentName().getClassName(),
reason);
} else {
EventLogTags.writeWmOnTopResumedLostCalled(mIdent, getComponentName().getClassName(),
reason);
}
}
/** 30064 wm_on_top_resumed_gained_called (Token|1|5),(Component Name|3),(Reason|3) */
public static final int WM_ON_TOP_RESUMED_GAINED_CALLED = 30064;
/** 30065 wm_on_top_resumed_lost_called (Token|1|5),(Component Name|3),(Reason|3) */
public static final int WM_ON_TOP_RESUMED_LOST_CALLED = 30065;
1.2 postExecute
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mOnTop) {
return;
}
// The loss of top resumed state can always be reported immediately in postExecute
// because only three cases are possible:
// 1. Activity is in RESUMED state now and it just handled the callback in #execute().
// 2. Activity wasn't RESUMED yet, which means that it didn't receive the top state yet.
// 3. Activity is PAUSED or in other lifecycle state after PAUSED. In this case top resumed
// state loss was already called right before pausing.
ActivityClient.getInstance().activityTopResumedStateLost();
}
public static ActivityClient getInstance() {
return sInstance.get();
}
private static final Singleton<ActivityClient> sInstance = new Singleton<ActivityClient>() {
@Override
protected ActivityClient create() {
return new ActivityClient();
}
};
/**
* Reports after {@link Activity#onTopResumedActivityChanged(boolean)} is called for losing the
* top most position.
*/
public void activityTopResumedStateLost() {
try {
getActivityClientController().activityTopResumedStateLost();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
private static IActivityClientController getActivityClientController() {
final IActivityClientController controller = INTERFACE_SINGLETON.mKnownInstance;
return controller != null ? controller : INTERFACE_SINGLETON.get();
}
private static final ActivityClientControllerSingleton INTERFACE_SINGLETON =
new ActivityClientControllerSingleton();
private static class ActivityClientControllerSingleton
extends Singleton<IActivityClientController> {
/**
* A quick look up to reduce potential extra binder transactions. E.g. getting activity
* task manager from service manager and controller from activity task manager.
*/
IActivityClientController mKnownInstance;
@Override
protected IActivityClientController create() {
try {
return ActivityTaskManager.getService().getActivityClientController();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
返回ATMS的成员mActivityClientController的Bp端
@Override
public IActivityClientController getActivityClientController() {
return mActivityClientController;
}
ActivityClientController mActivityClientController;
其提供客户端调用以activityXXX通知systemserver,如客户端pause后,就调用activityPaused通知systemSever。
/**
* Server side implementation for the client activity to interact with system.
*
* @see android.app.ActivityClient
*/
class ActivityClientController extends IActivityClientController.Stub {
/** Wrapper around VoiceInteractionServiceManager. */
private AssistUtils mAssistUtils;
void onSystemReady() {
mAssistUtils = new AssistUtils(mContext);
}
@Override
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling)
}
@Override
public void activityResumed(IBinder token, boolean handleSplashScreenExit)
@Override
public void activityTopResumedStateLost()
@Override
public void activityPaused(IBinder token)
@Override
public void activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState,
CharSequence description)
@Override
public void activityDestroyed(IBinder token)
@Override
public void activityRelaunched(IBinder token)
这里通知系统是调用activityTopResumedStateLost
@Override
public void activityTopResumedStateLost() {
final long origId = Binder.clearCallingIdentity();
synchronized (mGlobalLock) {
mTaskSupervisor.handleTopResumedStateReleased(false /* timeout */);
}
Binder.restoreCallingIdentity(origId);
}
然后调用ActivityTaskSupervisor的对应方法
/**
* Handle a loss of top resumed state by an activity - update internal state and inform next top
* activity if needed.
*/
void handleTopResumedStateReleased(boolean timeout) {
ProtoLog.v(WM_DEBUG_STATES, "Top resumed state released %s",
(timeout ? "(due to timeout)" : "(transition complete)"));
//移除消息,避免超时
mHandler.removeMessages(TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG);
if (!mTopResumedActivityWaitingForPrev) {
// Top resumed activity state loss already handled.
return;
}
//topResuemActivity在等待Pre,pre已经pause完成,因此这为false
mTopResumedActivityWaitingForPrev = false;
scheduleTopResumedActivityStateIfNeeded();
}
private final ActivityTaskSupervisorHandler mHandler;
mHandler的looper为SystemServer主线程looper
scheduleTopResumedActivityStateIfNeeded为如果topResumedActivity改变了就发送一个TopResumedActivityChangeItem
```java
/** Schedule top resumed state change if previous top activity already reported back. */
private void scheduleTopResumedActivityStateIfNeeded() {
if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) {
//没有执行,因为mTopResumedActivity 为null
mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */);
}
}
总结:TopResumedActivityChangeItem 主要是
# 2 PauseActivityItem
1. preExecute为空
2. execute
```java
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);
}
-
postExecute :负责通知服务端
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); }
回调
TopResumedActivityChangeItem
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately))
1 execute
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);
}
@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 表示用户离开该应用,对于pause而言,这里问true,finished表示该此处理是否完成
pip就是picture in picture 画中画
final void performUserLeavingActivity(ActivityClientRecord r) {
mInstrumentation.callActivityOnPictureInPictureRequested(r.activity);
mInstrumentation.callActivityOnUserLeaving(r.activity);
}
/**
* Perform calling of an activity's {@link Activity#onUserLeaveHint} method.
* The default implementation simply calls through to that method.
*
* @param activity The activity being notified that the user has navigated away
*/
public void callActivityOnUserLeaving(Activity activity) {
activity.performUserLeaving();
}
调用activity的onUserInteraction和onUserLeaveHint方法,该方法是空方法,应用能够重写该方法。
final void performUserLeaving() {
onUserInteraction();
onUserLeaveHint();
}
看一下 performPauseActivity(r, finished, reason, pendingActions);
/**
* Pause the activity.
* @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
*/
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;
}
//false
// 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;
}
对于pause而言finished为false。
performPauseActivityIfNeeded(r, reason);
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);
}
/**
* Perform calling of an activity's {@link Activity#onPause} method. The
* default implementation simply calls through to that method.
*
* @param activity The activity being paused.
*/
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
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;
// MIUI ADD:
long startTime = SystemClock.uptimeMillis();
//这里-----------
onPause();
// MIUI MOD: START
// EventLogTags.writeWmOnPausedCalled(mIdent, getComponentName().getClassName(),
// "performPause");
long took = SystemClock.uptimeMillis() - startTime;
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause", took);
checkLifecycleTime(took, SLOW_ON_PAUSE_THRESHOLD_MS, "onPause");
// END
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);
}
onPause执行完打印
onpause前执行这个
private void dispatchActivityPrePaused() {
getApplication().dispatchActivityPrePaused(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPrePaused(this);
}
}
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
/* package */ void dispatchActivityPrePaused(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPrePaused(activity);
}
}
}
@UnsupportedAppUsage
private Object[] collectActivityLifecycleCallbacks() {
Object[] callbacks = null;
synchronized (mActivityLifecycleCallbacks) {
if (mActivityLifecycleCallbacks.size() > 0) {
callbacks = mActivityLifecycleCallbacks.toArray();
}
}
return callbacks;
}
private Object[] collectActivityLifecycleCallbacks() {
Object[] callbacks = null;
synchronized (mActivityLifecycleCallbacks) {
if (mActivityLifecycleCallbacks.size() > 0) {
callbacks = mActivityLifecycleCallbacks.toArray();
}
}
return callbacks;
}
Activity的mActivityLifecycleCallbacks是有值的
TopResumedActivityChangeItem