今天开始写Android 10 Activity启动流程,主要目的在于巩固自己学到。
每次调用startActivity到显示新的Activity的过程,我从未关心过,不知道它是否跨进程调用,垮了几次进程,进程之间是如何通信,任务栈关系如何,每个Activity的信息又是如何处理,进程之间Activity又是如何做到消息同步等等
调用startActivity()最后代码执行都会跳转到startActivityForResult()
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
...
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
参数mMainThread.getApplicationThread()实际是ApplicationThread,是ActivityThread内部类,继承IApplicationThread.Stub,通过继承能看出提供给其他进程调用。
参数mToken我们要记住它,它是负责跨进程通信(Activity跨进程信息同步)。举例:ActivityA跳转到ActivityB此时mToken不为空,让下一个进程能找到ActivityA信息。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
此时我们可以看到启动Activity马上要跨进程
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
通过上面代码,现在代码分析到ActivityTaskManagerService 继承IActivityTaskManager.Stub ,这个进程主要是分担了ActivityManagerService的一些功能。我们可以主要到setMayWait(userId),帮助我们分析跳转到下面方法的走向。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
...
//解析数据
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
0 /* matchFlags */,
computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
...
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
...
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
Binder.restoreCallingIdentity(origId);
...
return res;
}
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
...
mLastStartActivityRecord[0] = null;
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
return getExternalResult(mLastStartActivityResult);
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
...
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
//
sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
...
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
...
mController.doPendingActivityLaunches(false);
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
...
return res;
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent,
String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
ActivityOptions options, ActivityRecord sourceRecord) {
mAtmService = _service;
mRootActivityContainer = _service.mRootActivityContainer;
appToken = new Token(this, _intent);
...
}
static class Token extends IApplicationToken.Stub {
private final WeakReference weakActivity;
private final String name;
Token(ActivityRecord activity, Intent intent) {
weakActivity = new WeakReference<>(activity);
name = intent.getComponent().flattenToShortString();
}
private static @Nullable ActivityRecord tokenToActivityRecordLocked(Token token) {
if (token == null) {
return null;
}
ActivityRecord r = token.weakActivity.get();
if (r == null || r.getActivityStack() == null) {
return null;
}
return r;
}
}
ActivityRecord的大量成员变量都是记录Activity相关信息,每个Activity都有一个ActivityRecord。
局部变量 sourceRecord 这是发起启动Activity的信息,这个resultTo都是之前提到启动Activity的参数mToken。然后我们都要为新的Activity创建新的ActivityRecord, 在创建此对象的时候一起创建了的Token对象并且把ActivityRecord一起关联。继续在同一个类分析
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
} finally {
...
}
return result;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
...
boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTaskRecord() : null;
// Should this be considered a new task?
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
// 1 创建所需要的 ActivityDisplay,ActivityStack,TaskRecord
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
result = setTaskToCurrentTopOrCreateNewTask();
}
...
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTaskRecord().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
// If the target stack was not previously focusable (previous top running activity
// on that stack was not visible) then any prior calls to move the stack to the
// will not update the focused stack. If starting the new activity now allows the
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isFocusable()
&& !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
//2 与应用层交互
mRootActivityContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
}
...
return START_SUCCESS;
}
上述代码和下面的代码是同一个类里面,下面代码分为4个点,后面会一一列出来分析
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
if (mRestrictedBgActivity && (mReuseTask == null || !mReuseTask.containsAppUid(mCallingUid))
&& handleBackgroundActivityAbort(mStartActivity)) {
return START_ABORTED;
}
//1.获取或者创建合适任务ActivityStack对象,里面创建的ActivityDisplay且与之关联
mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
// Do no move the target stack to front yet, as we might bail if
// isLockTaskModeViolation fails below.
if (mReuseTask == null) {
//2.ActivityStack 创建TaskRecord实例并且与之关联添加到 mTaskHistory
final TaskRecord task = mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
mOptions);
//3.TaskRecord与ActivityRecord关联
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ " in new task " + mStartActivity.getTaskRecord());
} else {
addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
}
if (taskToAffiliate != null) {
mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
}
if (mService.getLockTaskController().isLockTaskModeViolation(
mStartActivity.getTaskRecord())) {
Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
if (mDoResume) {
//4.将要显示的ActivityStack移动到栈顶
mTargetStack.moveToFront("reuseOrNewTask");
}
return START_SUCCESS;
}
上述代码做了4件事情,分别用代码一一阐述
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
ActivityOptions aOptions) {
final TaskRecord task = r.getTaskRecord();
ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
if (stack != null) {
return stack;
}
}
private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
ActivityOptions aOptions) {
// We are reusing a task, keep the stack!
if (mReuseTask != null) {
return mReuseTask.getStack();
}
if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
|| mPreferredDisplayId != DEFAULT_DISPLAY) {
final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
final ActivityStack stack =
mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
return stack;
}
}
//frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
T getLaunchStack(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop,
@Nullable LaunchParamsController.LaunchParams launchParams) {
int taskId = INVALID_TASK_ID;
int displayId = INVALID_DISPLAY;
//Rect bounds = null;
...
if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) {
if (r != null) {
//获取在ActivityDisplay最顶端的stack
stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
launchParams);
if (stack != null) {
return stack;
}
}
//如果发现没有现成的ActivityDisplay则创建它并且添加到此类的mActivityDisplays与之关联
final ActivityDisplay display = getActivityDisplayOrCreate(displayId);
if (display != null) {
// 在ActivityDisplay创建ActivityStack对象,并且添加到ActivityDisplay的mStacks关联
stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
if (stack != null) {
return stack;
}
}
}
...
return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
}
1.首先在RootActivityContainer这个类创建ActivityDisplay(主屏幕)对象,然后添加在数组RootActivityContainer.mActivityDisplays与之关联。在ActivityDisplay创建ActivityStack对象,并且添加到ActivityDisplay的mStacks关联。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
boolean toTop, ActivityRecord activity, ActivityRecord source,
ActivityOptions options) {
//创建实例
final TaskRecord task = TaskRecord.create(
mService, taskId, info, intent, voiceSession, voiceInteractor);
// add the task to stack first, mTaskPositioner might need the stack association
//实例添加到ActivityStack.mTaskHistory与之关联
addTask(task, toTop, "createTaskRecord");
...
return task;
}
2.在ActivityStack创建TaskRecord对象,并且添加到数组ActivityStack.mTaskHistory与之关联。
3.这里都不把代码贴出来,其实都是ActivityRecord对象添加到数组TaskRecord.mActivities中且与之关联。
4.将要显示的ActivityStack移动到栈顶。
如图所示他们之间的关系,
以上都是ActivityDisplay,ActivityStack,TaskRecord,ActivityRecord他们之间的关系,了解了他们之间关系,对我们分析Activity启动流程很重要。
接下来我们分析发起调用的Activity执行暂停过程
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
...
// 1 创建所需要的 ActivityDisplay,ActivityStack,TaskRecord
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
...
//2 与应用层交互
mRootActivityContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
...
}
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
}
//frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
...
} finally {
mInResumeTopActivity = false;
}
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
//暂停上一个activity
pausing |= startPausingLocked(userLeaving, false, next, false);
}
...
//是否有所属的进程
if (next.attachedToProcess()) {
...
try {
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken);
// Deliver all pending results.
ArrayList a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
if (next.newIntents != null) {
transaction.addCallback(
NewIntentItem.obtain(next.newIntents, true /* resume */));
}
// Well the app will no longer be stopped.
// Clear app token stopped state in window manager if needed.
next.notifyAppResumed(next.stopped);
...
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
} catch (Exception e) {
// Whoops, need to restart this activity!
if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
+ lastState + ": " + next);
next.setState(lastState, "resumeTopActivityInnerLocked");
// lastResumedActivity being non-null implies there is a lastStack present.
if (lastResumedActivity != null) {
lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
}
Slog.i(TAG, "Restarting because process died: " + next);
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else if (SHOW_APP_STARTING_PREVIEW && lastFocusedStack != null
&& lastFocusedStack.isTopStackOnDisplay()) {
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwitch */);
}
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
} else {
//开始启动activity
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
...
if (prev.attachedToProcess()) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
//执行下面代码
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
...
}
}
...
}
经过上述流程,最后执行到了startPausingLocked这个方法。在调用scheduleTransaction方法是有个参数appToken需要我们留意,看是如何与应用进程Activity关联的,参数ActivityLifecycleItem看下面源码分析。
//frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
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;
}
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();
}
}
//frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
//frameworks/base/core/java/android/app/servertransaction
public class PauseActivityItem extends ActivityLifecycleItem {
@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.
//AMS需要同步数据了
ActivityTaskManager.getService().
(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
在上述的代码可以看出 ,最终调用了IApplicationThread.scheduleTransaction()方法实现了跨进程调用,现在我们看下PauseActivityItem这个类,它继承ClientTransactionItem,这个类最终继承了BaseClientRequest,实现了execute()方法,我先提一下,等会再下面的分析有用。
public final class ActivityThread extends ClientTransactionHandler {
private class ApplicationThread extends IApplicationThread.Stub
{
//上述代码最终调用到这个方法
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
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.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
}
}
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
先代码执行到应用进程里了,ActivityThread有个内部类H继承了Handler,通过发送指令EXECUTE_TRANSACTION,执行TransactionExecutor.execute方法。
//frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
...
final IBinder token = transaction.getActivityToken();
...
executeCallbacks(transaction);
//通过前后源码分析 执行这个方法暂停Activity
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
/** 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;
}
//这个token都是之前我反复提到的 appToken
final IBinder token = transaction.getActivityToken();
//1.这个ActivityClientRecord 都是记录应用进程Activity的信息,在地层都是通过这个token获取底层的这个ActivityRecord
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.
//2.开始执行生命周期
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
上述代码有两点需要我们注意
1.应用进程使用token都可以获取得到ActivityClientRecord,ActivityClientRecord 都是记录应用进程Activity的信息,在实例化ActivityClientRecord时候与之关联token(后面创建Activity源码会分析到)。
ActivityTaskManagerService 进程ActivityRecord记录的是Activity信息,在实例化ActivityRecord 都实例化了Token这个类并且持有ActivityRecord这个类的引用。
2.这都开始执行了暂停Activity的调用,都是前面提到的类PauseActivityItem执行execute()。
当我们看到下面代码的时候,有一种豁然开朗的感觉,离我们的目的地原来越近了。
//ActivityThread.java
@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
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;
}
}
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
...
// 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;
}
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;
//这个方法都是调用了 activity.performPause();
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);
}
上述代码看出,最后调用了activity.performPause();
这里都完整的分析了AMS到应用进程的暂停过程。
参考资料:Android 10.0 Activity启动详解