目录
- 1. 前言
- 2. 正文
- 2.1 Activity.finish() 方法
- 2.2 Activity.finish(int finishTask) 方法
- 2.3 ActivityManagerService.finishActivity() 方法
- 2.4 ActivityStack.requestFinishActivityLocked() 方法
- 2.5 ActivityStack.finishActivityLocked() 方法
- 2.6 ActivityStack.finishActivityLocked() 方法
- 2.7 ActivityStack.startPausingLocked() 方法
- 2.8 ClientLifecycleManager.scheduleTransaction() 方法
- 2.9 ClientLifecycleManager.scheduleTransaction() 方法
- 2.10 ClientTransaction.schedule() 方法
- 2.11 ApplicationThread.scheduleTransaction() 方法
- 2.12 ClientTransactionHandler.scheduleTransaction() 方法
- 2.13 ActivityThread.sendMessage() 方法
- 2.14 TransactionExecutor.execute() 方法
- 2.15 TransactionExecutor.executeLifecycleState() 方法
- 2.16 PauseActivityItem.execute() 方法
- 3. 最后
1. 前言
本文以 Android 9.0 源码为基础,分析 Activity
的 finish 过程。要进行分析,必须先确定好场景,不然就没有了方向。我们分析的场景是这样的:
MainActivity
通过 startActivityForResult
方法启动了 SecondActivity
,然后 SecondActivity
调用 finish()
方法关闭自己。
2. 正文
2.1 Activity.finish() 方法
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
DONT_FINISH_TASK_WITH_ACTIVITY
这个标记的含义是 Task isn’t finished when activity is finished,即当 Activity finish 掉时 Task 不会被 finish。
2.2 Activity.finish(int finishTask) 方法
- int finishTask, DONT_FINISH_TASK_WITH_ACTIVITY
/**
* Finishes the current activity and specifies whether to remove the task associated with this
* activity.
*/
private void finish(int finishTask) {
// mParent 是 null
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
// 把 setResult() 方法中设置的 mResultCode,mResultData,
// 赋值给 resultCode,resultData。
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (resultData != null) {
// 准备 resultData 这个 Intent 离开应用进程
resultData.prepareToLeaveProcess(this);
}
if (ActivityManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
// 标记 mFinished 值为 true。
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
// Activity was launched when user tapped a link in the Autofill Save UI - Save UI must
// be restored now.
if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_RESTORE,
mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
}
}
2.3 ActivityManagerService.finishActivity() 方法
- IBinder token, mToken,是在 Activity 中的 attach() 方法中被赋值的,它指向了我们想要 finish 的 Activity
- int resultCode, 这里按照为 Activity.RESULT_OK 来分析
- Intent resultData, 一个不为 null 的 Intent 对象
- int finishTask, DONT_FINISH_TASK_WITH_ACTIVITY
- 返回值 boolean,Activity 成功被关闭返回 true,仍在运行则返回 false
/**
* This is the internal entry point for handling Activity.finish().
*
* @param token The Binder token referencing the Activity we want to finish.
* @param resultCode Result code, if any, from this Activity.
* @param resultData Result data (Intent), if any, from this Activity.
* @param finishTask Whether to finish the task associated with this Activity.
*
* @return Returns true if the activity successfully finished, or false if it is still running.
*/
@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
// Refuse possible leaked file descriptors
if (resultData != null && resultData.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
// 根据 token 去获取对应的 ActivityRecord 对象,ActivityRecord 封装了 Activity 的信息。
ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
// 如果 r 为 null,就返回 true,表示这个 Activity 已经 finish 掉了。
return true;
}
// Keep track of the root activity of the task before we finish it
// 获取 ActivityRecord 对象所属的 TaskRecord,TaskRecord 封装了 Task 的信息。
TaskRecord tr = r.getTask();
// Returns the first non-finishing activity from the root.
// 从 Task 底部开始,返回第一个没有正在 finish 的 Activity。
ActivityRecord rootR = tr.getRootActivity();
if (rootR == null) {
Slog.w(TAG, "Finishing task with all activities already finished");
}
// Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
// finish.
if (mLockTaskController.activityBlockedFromFinish(r)) {
return false;
}
// mController 是 null,
// 延伸一下:mController 是 IActivityController 对象,它的真正实现是在
// ActivityManagerShellCommand.java 中的内部类:
// static final class MyActivityController extends IActivityController.Stub {}
// 而设置 mController 是通过 WatchDog 类的
// public void setActivityController(IActivityController controller) 方法
// AMS 的 public void setActivityController(IActivityController controller, boolean imAMonkey) 方法。
if (mController != null) {
// Find the first activity that is not finishing.
ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
try {
resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mController = null;
Watchdog.getInstance().setActivityController(null);
}
if (!resumeOK) {
Slog.i(TAG, "Not finishing activity because controller resumed");
return false;
}
}
}
final long origId = Binder.clearCallingIdentity();
try {
boolean res;
final boolean finishWithRootActivity =
finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; // false
// 不会进入下面的分支
if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY // false
|| (finishWithRootActivity && r == rootR)) {
// If requested, remove the task that is associated to this activity only if it
// was the root activity in the task. The result code and data is ignored
// because we don't support returning them across task boundaries. Also, to
// keep backwards compatibility we remove the task from recents when finishing
// task with root activity.
res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
finishWithRootActivity, "finish-activity");
if (!res) {
Slog.i(TAG, "Removing task failed to finish activity");
}
} else { // 进入下面这个分支
// tr 是一个 TaskRecord 对象,tr.getStack() 获取的是一个 ActivityStack 对象。
res = tr.getStack().requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);
if (!res) {
Slog.i(TAG, "Failed to finish by app-request");
}
}
return res;
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
2.4 ActivityStack.requestFinishActivityLocked() 方法
- IBinder token, mToken,是在 Activity 中的 attach() 方法中被赋值的,它指向了我们想要 finish 的 Activity
- int resultCode, 这里按照为 Activity.RESULT_OK 来分析
- Intent resultData, 一个不为 null 的 Intent 对象
- String reason, “app-request”
- boolean oomAdj, true
- 返回值 boolean,activity 被 finish 掉则返回 true,否则返回 false
/**
* @return Returns true if the activity is being finished, false if for
* some reason it is being left as-is.
*/
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason, boolean oomAdj) {
// 根据 token 在 ActivityStack 里面找出 ActivityRecord 对象。
ActivityRecord r = isInStackLocked(token);
if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
"Finishing activity token=" + token + " r="
+ ", result=" + resultCode + ", data=" + resultData
+ ", reason=" + reason);
if (r == null) {
// 没找到,不能成功关闭 activity
return false;
}
finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
return true;
}
2.5 ActivityStack.finishActivityLocked() 方法
- ActivityRecord r, 对应于要关闭的 activity 的 信息封装对象
- int resultCode, 这里按照为 Activity.RESULT_OK 来分析
- Intent resultData, 一个不为 null 的 Intent 对象
- String reason, “app-request”
- boolean oomAdj, true
/**
* See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
*/
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj) {
// import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; 值为 true
return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
}
2.6 ActivityStack.finishActivityLocked() 方法
- ActivityRecord r, 对应于要关闭的 activity 的 信息封装对象
- int resultCode, 这里按照为 Activity.RESULT_OK 来分析
- Intent resultData, 一个不为 null 的 Intent 对象
- String reason, “app-request”
- boolean oomAdj, true
- boolean pauseImmediately, false
- 返回值 boolean,如果 activity 已经从 activity 列表移除了,就返回 true;否则返回 false。
/**
* @return Returns true if this activity has been removed from the history
* list, or false if it is still in the list and will be removed later.
*/
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj, boolean pauseImmediately) {
if (r.finishing) {
// 要关闭的 Activity 正在 finish,返回 false
Slog.w(TAG, "Duplicate finish request for " + r);
return false;
}
// 开始推迟布局阶段
mWindowManager.deferSurfaceLayout();
try {
r.makeFinishingLocked(); // 标记 r.finishing 为 true。
// 获取 ActivityRecord 所属的 TaskRecord 对象
final TaskRecord task = r.getTask();
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
r.userId, System.identityHashCode(r),
task.taskId, r.shortComponentName, reason);
// 获取 TaskRecord 里持有的 ActivityRecord 集合
final ArrayList<ActivityRecord> activities = task.mActivities;
// 找出当前的 ActivityRecord 在集合中的索引
final int index = activities.indexOf(r);
if (index < (activities.size() - 1)) { // 不是最顶层的条目
// ActivityRecord有一个属性是frontOfTask,表示ActivityRecord是否为TaskRecord的根Activity。
// 该函数设置TaskRecord中所有ActivityRecord的frontOfTask属性(is this the root activity of its task?),
// 从栈底往上开始遍历,
// 第一个不处于finishing状态的ActivityRecord的frontOfTask属性置成true,其他都为false
task.setFrontOfTask();
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
// If the caller asked that this activity (and all above it)
// be cleared when the task is reset, don't lose that information,
// but propagate it up to the next activity.
ActivityRecord next = activities.get(index+1);
next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
}
}
// 暂停键盘事件的分发
r.pauseKeyDispatchingLocked();
// 调整处于焦点的 ActivityStack
adjustFocusedActivityStack(r, "finishActivity");
finishActivityResultsLocked(r, resultCode, resultData);
final boolean endTask = index <= 0 && !task.isClearingToReuseTask(); // false
final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE; // TRANSIT_ACTIVITY_CLOSE
if (mResumedActivity == r) { // mResumedActivity 是 SecondActivity,r 也是 SecondActivity,进入此分支
if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare close transition: finishing " + r);
if (endTask) {
mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(
task.taskId);
}
mWindowManager.prepareAppTransition(transit, false);
// Tell window manager to prepare for this one to be removed.
r.setVisibility(false);
if (mPausingActivity == null) { // 进入此分支
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"finish() => pause with userLeaving=false");
startPausingLocked(false, false, null, pauseImmediately);
}
if (endTask) { // false
mService.getLockTaskController().clearLockedTask(task);
}
} else if (!r.isState(PAUSING)) {
// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
if (r.visible) {
prepareActivityHideTransitionAnimation(r, transit);
}
final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE
: FINISH_AFTER_PAUSE;
final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj,
"finishActivityLocked") == null;
// The following code is an optimization. When the last non-task overlay activity
// is removed from the task, we remove the entire task from the stack. However,
// since that is done after the scheduled destroy callback from the activity, that
// call to change the visibility of the task overlay activities would be out of
// sync with the activitiy visibility being set for this finishing activity above.
// In this case, we can set the visibility of all the task overlay activities when
// we detect the last one is finishing to keep them in sync.
if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
for (ActivityRecord taskOverlay : task.mActivities) {
if (!taskOverlay.mTaskOverlay) {
continue;
}
prepareActivityHideTransitionAnimation(taskOverlay, transit);
}
}
return removedActivity;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
}
return false;
} finally {
// 继续布局阶段
mWindowManager.continueSurfaceLayout();
}
}
2.6.1 ActivityStack.finishActivityResultsLocked() 方法
- ActivityRecord r, 对应于要关闭的 activity 的 信息封装对象
- int resultCode, 这里按照为 Activity.RESULT_OK 来分析
- Intent resultData, 一个不为 null 的 Intent 对象
private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
// send the result
ActivityRecord resultTo = r.resultTo; // MainActivity
if (resultTo != null) { // resultTo 不是 null
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
+ " who=" + r.resultWho + " req=" + r.requestCode
+ " res=" + resultCode + " data=" + resultData);
if (resultTo.userId != r.userId) {
if (resultData != null) {
resultData.prepareToLeaveUser(r.userId);
}
}
if (r.info.applicationInfo.uid > 0) {
mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
resultTo.packageName, resultData,
resultTo.getUriPermissionsLocked(), resultTo.userId);
}
// 把 result 相关信息,放入将来要接收这些信息的 Activity 的 ActivityRecord 对象中。
resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
resultData);
r.resultTo = null;
}
else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
// Make sure this HistoryRecord is not holding on to other resources,
// because clients have remote IPC references to this object so we
// can't assume that will go away and want to avoid circular IPC refs.
r.results = null;
r.pendingResults = null;
r.newIntents = null;
r.icicle = null;
}
这里需要再看一下 ActivityRecord.addResultLocked() 方法:
ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
void addResultLocked(ActivityRecord from, String resultWho,
int requestCode, int resultCode,
Intent resultData) {
// 把信息封装成 ActivityResult 对象,保存在集合中。
ActivityResult r = new ActivityResult(from, resultWho,
requestCode, resultCode, resultData);
if (results == null) {
results = new ArrayList<ResultInfo>();
}
results.add(r);
}
2.7 ActivityStack.startPausingLocked() 方法
- boolean userLeaving, false
- boolean uiSleeping, false
- ActivityRecord resuming, null
- boolean pauseImmediately, false
- 返回值 boolean, 如果一个 activity 当前处于 PAUSING 状态,则返回 true。
/**
* Start pausing the currently resumed activity. It is an error to call this if there
* is already an activity being paused or there is no resumed activity.
*
* @param userLeaving True if this should result in an onUserLeaving to the current activity.
* @param uiSleeping True if this is happening with the user interface going to sleep (the
* screen turning off).
* @param resuming The activity we are currently trying to resume or null if this is not being
* called as part of resuming the top activity, so we shouldn't try to instigate
* a resume here if not null.
* @param pauseImmediately True if the caller does not want to wait for the activity callback to
* complete pausing.
* @return Returns true if an activity now is in the PAUSING state, and we are waiting for
* it to tell us when it is done.
*/
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
if (mPausingActivity != null) { // mPausingActivity 是 null
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.getState());
if (!shouldSleepActivities()) {
// Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients.
completePauseLocked(false, resuming);
}
}
ActivityRecord prev = mResumedActivity; // 就是 SecondActivity
if (prev == null) { // 不进入此分支
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
if (prev == resuming) { // false
Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
return false;
}
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
mPausingActivity = prev; // mPausingActivity 指向 SecondActivity
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
// 设置 SecondActivity 的状态,把 ActivityStack 的 mResumedActivity 置为 null。
prev.setState(PAUSING, "startPausingLocked");
prev.getTask().touchActiveTime();
clearLaunchTime(prev);
mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
mService.updateCpuStats();
if (prev.app != null && prev.app.thread != null) { // 进入此分支
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
mService.updateUsageStats(prev, false);
// 调用这里,开始执行转换
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else { // 不进入此分支
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
if (mPausingActivity != null) { // 进入此分支
// Have the window manager pause its key dispatching until the new
// activity has started. If we're pausing the activity just because
// the screen is being turned off and the UI is sleeping, don't interrupt
// key dispatch; the same activity will pick it up again on wakeup.
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
} else if (DEBUG_PAUSE) {
Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
}
if (pauseImmediately) { // false
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
completePauseLocked(false, resuming);
return false;
} else {
schedulePauseTimeout(prev);
return true;
}
} else { // 不进入此分支
// This activity failed to schedule the
// pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
if (resuming == null) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
}
2.7.1 PauseActivityItem.obtain() 方法
我们需要看一下 PauseActivityItem
调用静态方法 obtain() 的源码:
PauseActivityItem
是 ActivityLifecycleItem
的子类,它的作用是请求把一个 activity 迁移到 paused 状态。
/**
* Request to move an activity to paused state.
* @hide
*/
public class PauseActivityItem extends ActivityLifecycleItem {
private static final String TAG = "PauseActivityItem";
private boolean mFinished;
private boolean mUserLeaving;
private int mConfigChanges;
private boolean mDontReport;
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public int getTargetState() {
return ON_PAUSE;
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) {
return;
}
try {
// TODO(lifecycler): Use interface callback instead of AMS.
ActivityManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
// ObjectPoolItem implementation
private PauseActivityItem() {}
/*
boolean finished, true,这是在 ActivityRecord.makeFinishingLocked() 方法中修改为 true 的。
boolean userLeaving, false
int configChanges,
boolean dontReport, false
*/
/** 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;
}
/** Obtain an instance initialized with default params. */
public static PauseActivityItem obtain() {
PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
if (instance == null) {
instance = new PauseActivityItem();
}
instance.mFinished = false;
instance.mUserLeaving = false;
instance.mConfigChanges = 0;
instance.mDontReport = true;
return instance;
}
@Override
public void recycle() {
super.recycle();
mFinished = false;
mUserLeaving = false;
mConfigChanges = 0;
mDontReport = false;
ObjectPool.recycle(this);
}
// Parcelable implementation
/** Write to Parcel. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeBoolean(mFinished);
dest.writeBoolean(mUserLeaving);
dest.writeInt(mConfigChanges);
dest.writeBoolean(mDontReport);
}
/** Read from Parcel. */
private PauseActivityItem(Parcel in) {
mFinished = in.readBoolean();
mUserLeaving = in.readBoolean();
mConfigChanges = in.readInt();
mDontReport = in.readBoolean();
}
public static final Creator<PauseActivityItem> CREATOR =
new Creator<PauseActivityItem>() {
public PauseActivityItem createFromParcel(Parcel in) {
return new PauseActivityItem(in);
}
public PauseActivityItem[] newArray(int size) {
return new PauseActivityItem[size];
}
};
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PauseActivityItem other = (PauseActivityItem) o;
return mFinished == other.mFinished && mUserLeaving == other.mUserLeaving
&& mConfigChanges == other.mConfigChanges && mDontReport == other.mDontReport;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (mFinished ? 1 : 0);
result = 31 * result + (mUserLeaving ? 1 : 0);
result = 31 * result + mConfigChanges;
result = 31 * result + (mDontReport ? 1 : 0);
return result;
}
@Override
public String toString() {
return "PauseActivityItem{finished=" + mFinished + ",userLeaving=" + mUserLeaving
+ ",configChanges=" + mConfigChanges + ",dontReport=" + mDontReport + "}";
}
}
2.8 ClientLifecycleManager.scheduleTransaction() 方法
- @NonNull IApplicationThread client, mMainThread.getApplicationThread()类型转换得到的IApplicationThread对象,
- @NonNull IBinder activityToken, mToken
- @NonNull ClientTransactionItem callback, PauseActivityItem 对象
/**
* 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);
}
2.8.1 ClientLifecycleManager.transactionWithState() 方法
- @NonNull IApplicationThread client, mMainThread.getApplicationThread()类型转换得到的IApplicationThread对象,
- @NonNull IBinder activityToken, mToken
- @NonNull ClientTransactionItem callback, PauseActivityItem 对象
- 返回值 ClientTransaction
/**
* @return A new instance of {@link ClientTransaction} with a single lifecycle state request.
*
* @see ClientTransaction
* @see ClientTransactionItem
*/
private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
@NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
// Set the lifecycle state in which the client should be after executing the transaction.
clientTransaction.setLifecycleStateRequest(stateRequest);
return clientTransaction;
}
2.9 ClientLifecycleManager.scheduleTransaction() 方法
/**
* Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
* @param transaction A sequence of client transaction items.
* @throws RemoteException
*
* @see 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.
transaction.recycle();
}
}
2.10 ClientTransaction.schedule() 方法
/**
* 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 是 IApplicationThread 类型
mClient.scheduleTransaction(this);
}
2.11 ApplicationThread.scheduleTransaction() 方法
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
2.12 ClientTransactionHandler.scheduleTransaction() 方法
ClientTransactionHandler
是 ActivityThread
的基类
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
2.13 ActivityThread.sendMessage() 方法
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) { // false
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
可以看到 mH 的 声明:
final H mH = new H();
而 H 是一个 Handler 的子类:
class H extends Handler {
在 H 的 handleMessage() 方法中,可以找到:
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
// 把传递过来的 ClientTransaction 对象交给 mTransactionExecutor 去执行
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;
那么 TransactionExecutor 是什么呢?
// An executor that performs multi-step transactions.
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
2.14 TransactionExecutor.execute() 方法
/**
* 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) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
// 没有设置 Callback
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
2.15 TransactionExecutor.executeLifecycleState() 方法
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
// 获取到的其实是 PauseActivityItem 对象
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
log("Resolving lifecycle state: " + lifecycleItem);
final IBinder token = transaction.getActivityToken();
// 根据 token,获取对应的 ActivityClientRecord 对象
// ActivityClientRecord 是 ActivityThread 的内部类
// 这个方法内部是调用 mActivities.get(token); 而 mActivity 是
// final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
// 而添加这个 mActivities 的地方是在 ActivityThread.performLaunchActivity() 方法中。
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);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
2.15.1 TransactionExecutor.cycleToPath() 方法
- ActivityClientRecord r,
- int finish, ON_PAUSE
- boolean excludeLastState,true
/**
* 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) {
final int start = r.getLifecycleState(); // ON_RESUME
log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
// mHelper 是成员变量,private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState); // []
// path 没有内容,什么都不做
performLifecycleSequence(r, path);
}
2.15.2 TransactionExecutorHelper.getLifecyclePath() 方法
贴出一些常量在这里,下面会用到:
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;
- int start, ON_RESUME 3
- int finish, ON_PAUSE 4
- boolean excludeLastState,true
/**
* 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) { // 4 >= 3, 进入此分支
// just go there
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i); // ON_PAUSE
}
} 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) { // true
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
return mLifecycleSequence; // []
}
2.16 PauseActivityItem.execute() 方法
/**
* Request to move an activity to paused state.
* @hide
*/
public class PauseActivityItem extends ActivityLifecycleItem {
private static final String TAG = "PauseActivityItem";
private boolean mFinished;
private boolean mUserLeaving;
private int mConfigChanges;
private boolean mDontReport;
/*
boolean finished, true,这是在 ActivityRecord.makeFinishingLocked() 方法中修改为 true 的。
boolean userLeaving, false
int configChanges,
boolean dontReport, false
*/
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
/*
token:
mFinished: true
mUserLeaving: false
mConfigChanges:
pendingActions:
*/
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public int getTargetState() {
return ON_PAUSE;
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) { // false
return;
}
try {
// TODO(lifecycler): Use interface callback instead of AMS.
ActivityManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
// ObjectPoolItem implementation
private PauseActivityItem() {}
/** 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;
}
/** Obtain an instance initialized with default params. */
public static PauseActivityItem obtain() {
PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
if (instance == null) {
instance = new PauseActivityItem();
}
instance.mFinished = false;
instance.mUserLeaving = false;
instance.mConfigChanges = 0;
instance.mDontReport = true;
return instance;
}
@Override
public void recycle() {
super.recycle();
mFinished = false;
mUserLeaving = false;
mConfigChanges = 0;
mDontReport = false;
ObjectPool.recycle(this);
}
// Parcelable implementation
/** Write to Parcel. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeBoolean(mFinished);
dest.writeBoolean(mUserLeaving);
dest.writeInt(mConfigChanges);
dest.writeBoolean(mDontReport);
}
/** Read from Parcel. */
private PauseActivityItem(Parcel in) {
mFinished = in.readBoolean();
mUserLeaving = in.readBoolean();
mConfigChanges = in.readInt();
mDontReport = in.readBoolean();
}
public static final Creator<PauseActivityItem> CREATOR =
new Creator<PauseActivityItem>() {
public PauseActivityItem createFromParcel(Parcel in) {
return new PauseActivityItem(in);
}
public PauseActivityItem[] newArray(int size) {
return new PauseActivityItem[size];
}
};
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PauseActivityItem other = (PauseActivityItem) o;
return mFinished == other.mFinished && mUserLeaving == other.mUserLeaving
&& mConfigChanges == other.mConfigChanges && mDontReport == other.mDontReport;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (mFinished ? 1 : 0);
result = 31 * result + (mUserLeaving ? 1 : 0);
result = 31 * result + mConfigChanges;
result = 31 * result + (mDontReport ? 1 : 0);
return result;
}
@Override
public String toString() {
return "PauseActivityItem{finished=" + mFinished + ",userLeaving=" + mUserLeaving
+ ",configChanges=" + mConfigChanges + ",dontReport=" + mDontReport + "}";
}
}