系列文章
Android S从桌面点击图标启动APP流程 (一)
Android S从桌面点击图标启动APP流程 (二)
Android 12的源码链接:
上文中讲到如下方法:
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately));
25. Server端-ClientLifecycleManager#scheduleTransaction
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken, @NonNull ClientTransactionItem callback) throws RemoteException { final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken, callback); scheduleTransaction(clientTransaction); }private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client, IBinder activityToken, @NonNull ClientTransactionItem callback) { final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken); clientTransaction.addCallback(callback); return clientTransaction; }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. 如果客户端不是 Binder 的实例 - 它是一个远程调用,此时回收对象是安全的。在 ActivityThread 中的客户端上执行事务后,将回收用于本地调用的所有对象。 transaction.recycle(); } }frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/** Get the target client of the transaction. */ public IApplicationThread getClient() { return mClient; }
这里是有一个aidl通信在的,aidl文件位置为如下,其作用为:用于与应用程序通信的系统专用 API。 这是应用程序在启动时提供给活动管理器的,以便活动管理器告诉应用程序它需要做的事情。
System private API for communicating with the application. This is given to the activity manager by an application when it starts up, for the activity manager to tell the application about things it needs to do.
frameworks/base/core/java/android/app/IApplicationThread.aidl
26. Client端-ApplicationThread#scheduleTransaction
frameworks/base/core/java/android/app/ActivityThread.java private class ApplicationThread extends IApplicationThread.Stub { ... @Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { ActivityThread.this.scheduleTransaction(transaction); } ... }
由于ActivityThread中没有重写scheduleTransaction,所以会调用到ActivityThread的父类ClientTransactionHandler中,ClientTransactionHandler中的scheduleTransaction方法如下。
frameworks/base/core/java/android/app/ActivityThread.javapublic final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {//继承父类,调用父类的方法
frameworks/base/core/java/android/app/ClientTransactionHandler.java
public abstract class ClientTransactionHandler { ... /** Prepare and schedule transaction for execution. */ void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); //会发送EXECUTE_TRANSACTION消息 } ...
frameworks/base/core/java/android/app/ActivityThread.java void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } private void sendMessage(int what, Object obj, int arg1) { sendMessage(what, obj, arg1, 0, false); } private void sendMessage(int what, Object obj, int arg1, int arg2) { sendMessage(what, obj, arg1, arg2, 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); } ------------------------------------------------------------------------ // An executor that performs multi-step transactions. private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this); ------------------------------------------------------------------------class H extends Handler { ... 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.系统进程内的客户端事务在客户端而不是 ClientLifecycle Manager 上回收,以避免在处理此消息之前被清除。 transaction.recycle(); } // TODO(lifecycler): Recycle locally scheduled transactions. break; ... }
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
解析事务。
* 首先,所有回调将按照它们在列表中出现的顺序执行。如果回调需要特定的执行前或执行后状态,则客户端将相应地进行转换。 然后客户端将循环到最终生命周期状态(如果提供)。否则,它将保持初始状态或回调所需的最后一个状态。
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.
它将执行销毁token对应的activity的事务,因此可以删除相应的待销毁记录。
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.
该activity尚未创建,但已被请求销毁,因此token的所有交易就像被取消一样。
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");
}
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
循环遍历回调请求的所有状态,并在适当的时候执行它们。
@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).
如果当最后一个回调的执行后状态与此事务中的activity请求的最终状态匹配时,我们不会在此处执行最后一次转换,而是在移动到最终状态时执行此操作(因为它可能包含来自服务器的其他参数)。
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) {//之前将PauseActivityItem.obtain add进了callback,所以此处可以get到这个callback
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());
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
--执行完execute后,会再执行postExecute通知Server端
item.execute(mTransactionHandler, token, mPendingActions);
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);
}
}
}
27. PauseActivityItem#execute
这里就走到了PauseActivityItem,马上要开始真正的pause操作了, ActivityThread继承了ClientTransactionHandler,所以最终会走进ActivityThread。
frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
public class PauseActivityItem extends ActivityLifecycleItem { ... @Override 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); } ...
28. ActivityThread#handlePauseActivity
frameworks/base/core/java/android/app/ActivityThread.javapublic 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; }
29. ActivityThread#performPauseActivity
final Bundle performPauseActivity(IBinder token, boolean finished, String reason, PendingTransactionActions pendingActions) { ActivityClientRecord r = mActivities.get(token); return r != null ? performPauseActivity(r, finished, reason, pendingActions) : null; }
30. ActivityThread#performPauseActivity
/** 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; } // Pre-Honeycomb apps always save their state before pausing final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb(); if (shouldSaveState) { callActivityOnSaveInstanceState(r); } performPauseActivityIfNeeded(r, reason); ... return shouldSaveState ? r.state : null; }
31. ActivityThread#performPauseActivityIfNeeded
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().
当pause activity时,始终报告top resumed的位置。如有必要,它将在 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);//更新pause的值
}
/** Update the current lifecycle state for internal bookkeeping. */
public void setState(@LifecycleState int newLifecycleState) {
mLifecycleState = newLifecycleState;
switch (mLifecycleState) {
case ON_CREATE:
paused = true;
stopped = true;
break;
case ON_START:
paused = true;
stopped = false;
break;
case ON_RESUME:
paused = false;
stopped = false;
break;
case ON_PAUSE:
paused = true;
stopped = false;
break;
case ON_STOP:
paused = true;
stopped = true;
break;
}
}
32. Instrumentation#callActivityOnPause
执行到这里,马上就要调用到prev activity的onPause方法了。
frameworks/base/core/java/android/app/Instrumentation.java
开始调用Activity的的onpause方法
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
33. Activity#performPause
终于调用到应用的onPause方法了,就开始执行activity的pause操作
frameworks/base/core/java/android/app/Activity.javafinal 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; onPause(); EventLogTags.writeWmOnPausedCalled(mIdent, getComponentName().getClassName(), "performPause"); 10-11 05:23:15.928 2461 2461 I wm_on_paused_called: [186282051,com.android.launcher3.uioverrides.QuickstepLauncher,performPause] 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); }
34. Activity#onPause
protected void onPause() { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this); dispatchActivityPaused(); if (mAutoFillResetNeeded) { if (!mAutoFillIgnoreFirstResumePause) { if (DEBUG_LIFECYCLE) Slog.v(TAG, "autofill notifyViewExited " + this); View focus = getCurrentFocus(); if (focus != null && focus.canNotifyAutofillEnterExitEvent()) { getAutofillManager().notifyViewExited(focus); } } else { // reset after first pause() if (DEBUG_LIFECYCLE) Slog.v(TAG, "autofill got first pause " + this); mAutoFillIgnoreFirstResumePause = false; } } notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_PAUSE); mCalled = true; }