voidscheduleTransaction(ClientTransaction transaction)throws RemoteException {final IApplicationThread client = transaction.getClient();// 1
transaction.schedule();// 2if(!(client instanceofBinder)){// 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();}}
classHextendsHandler{//...publicvoidhandleMessage(Message msg){switch(msg.what){case EXECUTE_TRANSACTION:// 1final ClientTransaction transaction =(ClientTransaction) msg.obj;// 2
mTransactionExecutor.execute(transaction);// 3if(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;}}}
@VisibleForTestingpublicvoidexecuteCallbacks(ClientTransaction transaction){final List<ClientTransactionItem> callbacks = transaction.getCallbacks();if(callbacks == null){// No callbacks to execute, return early.return;}log("Resolving callbacks");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();finalint finalState = finalStateRequest != null ? finalStateRequest.getTargetState(): UNDEFINED;// Index of the last callback that requests some post-execution state.finalint lastCallbackRequestingState =lastCallbackRequestingState(transaction);finalint size = callbacks.size();for(int i =0; i < size;++i){final ClientTransactionItem item = callbacks.get(i);// 1log("Resolving callback: "+ item);finalint postExecutionState = item.getPostExecutionState();finalint closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());if(closestPreExecutionState != UNDEFINED){cycleToPath(r, closestPreExecutionState);}
item.execute(mTransactionHandler, token, mPendingActions);// 2
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.finalboolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;cycleToPath(r, postExecutionState, shouldExcludeLastTransition);}}}
privatevoidexecuteLifecycleState(ClientTransaction transaction){final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();// 1if(lifecycleItem == null){// No lifecycle request, return early.return;}log("Resolving lifecycle state: "+ lifecycleItem);final IBinder token = transaction.getActivityToken();final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);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 */);// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);// 2
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);}