当我们在一个Activity中(或通过Context对象),调用startActivity()方法来启动另一个Activity的过程中发生了什么呢?这就是本文想跟大家分享的内容,我们一起通过源码的方式来看下Activity的启动过程。(本文是基于Android Q的源码)
?Activity的启动流程大体分为两步:找到要启动的Activity;然后启动它。(虽说有点像如何把大象装进冰箱,但也确实是那么回事,只不过每个步骤有更多细节)
找到Activity
?要想启动一个Activity,系统先要找到这个Activity的信息。我们以从一个Activity中启动另一个Activity为起点来分析Activity的启动过程,在这个过程种会涉及到系统查找要启动的Activity的过程,下面我们以时序图来分析Activity的启动过程:  ? 这只是Activity启动过程种的一小部分,Activity的启动的服务端是由ActivityTaskManagerService实现的,在ActivityTaskManagerService中Activity的启动又是由ActivityStarter来实现。对于系统如何找到要启动的Activity,大体分为两步:
- 得到ResolveInfo对象,实现方式是通过ActivityStackSuperVisor.resolveIntent()方法(最终是调用了PackageManagerService.resolveIntent()方法)解析而来;
- 得到ActivityInfo对象,在得到ResolveInfo对象后,加上一些逻辑判断得到ActivityInfo对象;至此系统就找到了需要启动的Activity;
而这两步都是在ActivityStarter.startActivityMayWait()方法中完成。
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) {
final Intent ephemeralIntent = new Intent(intent);
intent = new Intent(intent);
if (componentSpecified
&& !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
&& !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
&& !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
&& mService.getPackageManagerInternalLocked()
.isInstantAppInstallerComponent(intent.getComponent())) {
intent.setComponent(null );
componentSpecified = false;
}
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
0 ,
computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
if (rInfo == null) {
UserInfo userInfo = mSupervisor.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
UserManager userManager = UserManager.get(mService.mContext);
boolean profileLockedAndParentUnlockingOrUnlocked = false;
long token = Binder.clearCallingIdentity();
try {
UserInfo parent = userManager.getProfileParent(userId);
profileLockedAndParentUnlockingOrUnlocked = (parent != null)
&& userManager.isUserUnlockingOrUnlocked(parent.id)
&& !userManager.isUserUnlockingOrUnlocked(userId);
} finally {
Binder.restoreCallingIdentity(token);
}
if (profileLockedAndParentUnlockingOrUnlocked) {
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
}
}
}
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService.mGlobalLock) {
final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Starting activity when config will change = " + stack.mConfigWillChange);
final long origId = Binder.clearCallingIdentity();
if (aInfo != null &&
(aInfo.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
mService.mHasHeavyWeightFeature) {
if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
final WindowProcessController heavy = mService.mHeavyWeightProcess;
if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid
|| !heavy.mName.equals(aInfo.processName))) {
int appCallingUid = callingUid;
if (caller != null) {
WindowProcessController callerApp =
mService.getProcessController(caller);
if (callerApp != null) {
appCallingUid = callerApp.mInfo.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
SafeActivityOptions.abort(options);
return ActivityManager.START_PERMISSION_DENIED;
}
}
IIntentSender target = mService.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, "android",
appCallingUid, userId, null, null, 0, new Intent[] { intent },
new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
| PendingIntent.FLAG_ONE_SHOT, null);
Intent newIntent = new Intent();
if (requestCode >= 0) {
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
}
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
new IntentSender(target));
heavy.updateIntentForHeavyWeightActivity(newIntent);
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
aInfo.packageName);
newIntent.setFlags(intent.getFlags());
newIntent.setClassName("android",
HeavyWeightSwitcherActivity.class.getName());
intent = newIntent;
resolvedType = null;
caller = null;
callingUid = Binder.getCallingUid();
callingPid = Binder.getCallingPid();
componentSpecified = true;
rInfo = mSupervisor.resolveIntent(intent, null , userId,
0 , computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
}
}
}
}
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;
}
}
启动Activity
?在了解系统怎么找到要启动的Activity后,我们现在就来看下启动Activity的过程。在了解Activity启动过程前,我们先了解下Activity 栈结构模型
Activity结构模型
下面这幅图就是Activity(对应图中的ActivityRecord)在历史任务中的结构。 
数据结构描述
- RootActivityContainer : Activity 容器的根节点
- ActivityDisplay:每个实例代表系统中的一个显示屏幕,也就是说如果你的Android设备是多屏的,那么将会有多个ActivityDisplay实例。
- ActivityStack: Activity栈,用于表示管理栈中的Activity。
- TaskRecord:ActivityRecord列表的封装类,在ActivityStack中用于记录历史运行的Activity。
- ActivityRecord:ActivityRecord表示历史运行的Activity对象。
- 通过
dumpsys activity a 命令可查看当前设备的activity栈结构。
启动过程分析
对于上面的数据结构图,要有个基本掌握,这有助于我们理解Activity启动过程中的逻辑。我们先从ActivityStarter.startActivity()方法分析
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) {
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
int err = ActivityManager.START_SUCCESS;
final Bundle verificationBundle
= options != null ? options.popAppVerificationBundle() : null;
WindowProcessController callerApp = null;
if (caller != null) {
callerApp = mService.getProcessController(caller);
if (callerApp != null) {
callingPid = callerApp.getPid();
callingUid = callerApp.mInfo.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
}
}
final int userId = aInfo != null && aInfo.applicationInfo != null
? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
if (err == ActivityManager.START_SUCCESS) {
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
+ "} from uid " + callingUid);
}
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Will send result to " + resultTo + " " + sourceRecord);
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);
if (outActivity != null) {
outActivity[0] = r;
}
if (r.appTimeTracker == null && sourceRecord != null) {
r.appTimeTracker = sourceRecord.appTimeTracker;
}
final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
if (voiceSession == null && (stack.getResumedActivity() == null
|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
realCallingPid, realCallingUid, "Activity start")) {
if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
sourceRecord, startFlags, stack, callerApp));
}
ActivityOptions.abort(checkedOptions);
return ActivityManager.START_SWITCHES_CANCELED;
}
}
mService.onStartActivitySetDidAppSwitch();
mController.doPendingActivityLaunches(false);
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true , checkedOptions, inTask, outActivity, restrictedBgActivity);
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
return res;
}
?在此方法中主要完成以下事情:
?接下来,我们看下startActivityUnchecked()方法,这个方法很长也很复杂,我们把Activity启动分为以下几种情况来分析:
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);
final int preferredWindowingMode = mLaunchParams.mWindowingMode;
computeLaunchingTaskFlags();
computeSourceStack();
mIntent.setFlags(mLaunchFlags);
ActivityRecord reusedActivity = getReusableIntentActivity();
mSupervisor.getLaunchParamsController().calculate(
reusedActivity != null ? reusedActivity.getTaskRecord() : mInTask,
r.info.windowLayout, r, sourceRecord, options, PHASE_BOUNDS, mLaunchParams);
mPreferredDisplayId =
mLaunchParams.hasPreferredDisplay() ? mLaunchParams.mPreferredDisplayId
: DEFAULT_DISPLAY;
if (r.isActivityTypeHome() && !mRootActivityContainer.canStartHomeOnDisplay(r.info,
mPreferredDisplayId, true )) {
Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
return START_CANCELED;
}
if (reusedActivity != null) {
if (mService.getLockTaskController().isLockTaskModeViolation(
reusedActivity.getTaskRecord(),
(mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
final boolean clearTopAndResetStandardLaunchMode =
(mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
== (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
&& mLaunchMode == LAUNCH_MULTIPLE;
if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
mStartActivity.setTask(reusedActivity.getTaskRecord());
}
if (reusedActivity.getTaskRecord().intent == null) {
reusedActivity.getTaskRecord().setIntent(mStartActivity);
} else {
final boolean taskOnHome =
(mStartActivity.intent.getFlags() & FLAG_ACTIVITY_TASK_ON_HOME) != 0;
if (taskOnHome) {
reusedActivity.getTaskRecord().intent.addFlags(FLAG_ACTIVITY_TASK_ON_HOME);
} else {
reusedActivity.getTaskRecord().intent.removeFlags(FLAG_ACTIVITY_TASK_ON_HOME);
}
}
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| isDocumentLaunchesIntoExisting(mLaunchFlags)
|| isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
final TaskRecord task = reusedActivity.getTaskRecord();
final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
mLaunchFlags);
if (reusedActivity.getTaskRecord() == null) {
reusedActivity.setTask(task);
}
if (top != null) {
if (top.frontOfTask) {
top.getTaskRecord().setIntent(mStartActivity);
}
deliverNewIntent(top);
}
}
mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
(false , reusedActivity);
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
final ActivityRecord outResult =
outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
outActivity[0] = reusedActivity;
}
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
resumeTargetStackIfNeeded();
return START_RETURN_INTENT_TO_CALLER;
}
if (reusedActivity != null) {
setTaskFromIntentActivity(reusedActivity);
if (!mAddingToTask && mReuseTask == null) {
resumeTargetStackIfNeeded();
if (outActivity != null && outActivity.length > 0) {
outActivity[0] = reusedActivity.finishing
? reusedActivity.getTaskRecord().getTopActivity() : reusedActivity;
}
return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
}
}
}
}
?注释中已经做了部分说明,这里有个比较重要的方法getReusableIntentActivity() ,这个方法是判断要启动的ActivityRecord是否加入到现有的TaskRecord中,这个判断会涉及到launchMode、taskAffinity和launchFlag的设定,这里我们就不展开了,以后的文章我们再来详细了解,这里我们先举个例子说明:
<activity android:name="com.example.ltst.MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.ltst.activity.ActivitySingleTaskCustomAffinity"
android:taskAffinity=".singleTaskAffinity"
android:launchMode="singleTask"/>
<activity android:name="com.example.ltst.activity.ActivitySingleTask"
android:launchMode="singleTask">
</activity>
<activity android:name="com.example.ltst.activity.ActivitySingleInstance"
android:launchMode="singleInstance"/>
<activity android:name="com.example.ltst.activity.ActivityStandard"/>
?如上所示,我们定义了五个Activity,现在从MainActivity中分别启动另外四个Activity:
- MainActivity > ActivitySingleTaskCustomAffinity, MainActivity的taskAffinity为默认的包名,ActivitySingleTaskCustomeAffinity自定义了taskAffinity,所以这种情况
getReusableIntentActivity() 返回为null. - MainActivity > ActivitySingleTask,MainActivity和ActivitySingleTask的launchMode和taskAffinity(不显示定义的话默认为应用包名)都是一样的,这个时候
getReusableIntentActivity() 返回的就是MainActivity的ActivityRecord对象; - MainActivity > ActivitySingleInstance,launchMode为singleInstance比较特殊,该模式下TaskRecord下只能有一个ActivityRecord,由于ActivitySingleInstance对应的TaskRecord还没有被创建过,所以此时
getReusableIntentActivity() 返回的也是null。 - MainActivity > ActivityStandard, 这种情况
getReusableIntentActivity 返回的是nul,这是因为getReusableIntentActivity() 里面有判断要启动Activity的launchMode和launchFlag,如果launchFlag没有设置FLAG_ACTIVITY_NEW_TASK且launchMode不为singleInstance和singleTask,则会返回null,但这也不是意味着ActivityStandard会被放入其他的TaskRecord中,它还是会被加入到MainActivity所在的TaskRecord中。
对于已经被启动过的Activity,且它对应的ActivityRecord还在ActivityStack中的时候,再次启动该Activity的流程(也就是App热启动的情况)大概是这样的: 
?在ActivityStack.resumeTopActivityInnerLocke()方法中会触发一个ResumeActivityItem请求的事务,最后事务处理会执行ResumeActivityItem.excute()方法中的任务。ResumeActivityItem.excute()方法会调用ActivityThread.handleResuemActivity().
?如上面的例子中所述,对于创建新的TaskRecord有多种情况,我们来看另一种情况——App冷启动,这种情况会涉及到ActivityStack和TaskRecord的创建。
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);
if (mStartActivity.packageName == null) {
final ActivityStack sourceStack = mStartActivity.resultTo != null
? mStartActivity.resultTo.getActivityStack() : null;
if (sourceStack != null) {
sourceStack.sendActivityResultLocked(-1 , mStartActivity.resultTo,
mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
null );
}
ActivityOptions.abort(mOptions);
return START_CLASS_NOT_FOUND;
}
final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
final ActivityRecord topFocused = topStack.getTopActivity();
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.mActivityComponent.equals(mStartActivity.mActivityComponent)
&& top.mUserId == mStartActivity.mUserId
&& top.attachedToProcess()
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
&& (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
if (dontStart) {
topStack.mLastPausedActivity = null;
if (mDoResume) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
return START_RETURN_INTENT_TO_CALLER;
}
deliverNewIntent(top);
mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode,
mPreferredDisplayId, topStack);
return START_DELIVERED_TO_TOP;
}
boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTaskRecord() : null;
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
result = setTaskToCurrentTopOrCreateNewTask();
}
if (result != START_SUCCESS) {
return result;
}
mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
mService.getPackageManagerInternalLocked().grantEphemeralAccess(
mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
UserHandle.getAppId(mCallingUid));
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
mStartActivity.getTaskRecord().taskId);
}
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTaskRecord());
mTargetStack.mLastPausedActivity = null;
mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded(
false , mStartActivity);
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTaskRecord().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
if (mTargetStack.isFocusable()
&& !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mRootActivityContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
}
mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
preferredWindowingMode, mPreferredDisplayId, mTargetStack);
return START_SUCCESS;
}
?冷启动的情况下,setTaskFromReuseOrCreateNewTask 会创建要启动的Activity对应的ActivityRecord所在的Activitystack和TaskRecord。然后经过mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions); 实现启动Activity的逻辑;RootActivityContainer.resumeFocusedStacksTopActivities()方法最终会调用ActivityStack.resumeTopActivityInnerLocked() , 启动Activity的主要逻辑就在该方法中。这个方法比较长,我们只截取部分说明
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (!mService.isBooting() && !mService.isBooted()) {
return false;
}
if (DEBUG_STATES) Slog.v(TAG_STATES,
"resumeTopActivityInnerLocked: ", new RuntimeException("resumeTopActivityInnerLocked").fillInStackTrace());
ActivityRecord next = topRunningActivityLocked(true );
final boolean hasRunningActivity = next != null;
if (hasRunningActivity && !isAttached()) {
return false;
}
mRootActivityContainer.cancelInitializingActivities();
boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
if (!hasRunningActivity) {
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}
next.delayedResume = false;
final ActivityDisplay display = getDisplay();
if (mResumedActivity == next && next.isState(RESUMED)
&& display.allResumedActivitiesComplete()) {
executeAppTransition(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Top activity resumed " + next);
return false;
}
if (!next.canResumeByCompat()) {
return false;
}
if (shouldSleepOrShutDownActivities()
&& mLastPausedActivity == next
&& mRootActivityContainer.allPausedActivitiesComplete()) {
boolean nothingToResume = true;
if (!mService.mShuttingDown) {
final boolean canShowWhenLocked = !mTopActivityOccludesKeyguard
&& next.canShowWhenLocked();
final boolean mayDismissKeyguard = mTopDismissingKeyguardActivity != next
&& next.mAppWindowToken != null
&& next.mAppWindowToken.containsDismissKeyguardWindow();
if (canShowWhenLocked || mayDismissKeyguard) {
ensureActivitiesVisibleLocked(null , 0 ,
!PRESERVE_WINDOWS);
nothingToResume = shouldSleepActivities();
}
}
if (nothingToResume) {
executeAppTransition(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Going to sleep and all paused");
return false;
}
}
if (!mService.mAmInternal.hasStartedUserState(next.mUserId)) {
Slog.w(TAG, "Skipping resume of top activity " + next
+ ": user " + next.mUserId + " is stopped");
return false;
}
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
if (!mRootActivityContainer.allPausedActivitiesComplete()) {
if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
"resumeTopActivityLocked: Skip resume: some activity pausing.");
return false;
}
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
boolean lastResumedCanPip = false;
ActivityRecord lastResumed = null;
final ActivityStack lastFocusedStack = display.getLastFocusedStack();
if (lastFocusedStack != null && lastFocusedStack != this) {
lastResumed = lastFocusedStack.mResumedActivity;
if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
if(DEBUG_USER_LEAVING) Slog.i(TAG_USER_LEAVING, "Overriding userLeaving to false"
+ " next=" + next + " lastResumed=" + lastResumed);
userLeaving = false;
}
lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
"resumeTopActivity", userLeaving );
}
final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
&& !lastResumedCanPip;
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, false);
}
if (pausing && !resumeWhilePausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
"resumeTopActivityLocked: Skip resume: need to start pausing");
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false ,
true , false );
}
if (lastResumed != null) {
lastResumed.setWillCloseOrEnterPip(true);
}
return true;
} else if (mResumedActivity == next && next.isState(RESUMED)
&& display.allResumedActivitiesComplete()) {
executeAppTransition(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
return true;
}
}
?上面截取的是让activity 栈中的Activity先进入pause状态的逻辑。这也是为什么应用A启动应用B的时候,应用A的Activity的onPause()方法会在应用B的Activity的onCreate()方法之前调用(这里没有考虑分屏的情况)。getDisplay().pauseBackStacks(userLeaving, next, false); 会让前台App的Activity进入pause状态,该方法会调用到ActivityStack.startPausingLocked()方法,在这个方法中主要的逻辑是发送一个PauseActivityItem的事务。
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.getState());
if (!shouldSleepActivities()) {
completePauseLocked(false, resuming);
}
}
ActivityRecord prev = mResumedActivity;
if (prev == null) {
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return false;
}
if (prev == resuming) {
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;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
prev.setState(PAUSING, "startPausingLocked");
prev.getTaskRecord().touchActiveTime();
clearLaunchTime(prev);
mService.updateCpuStats();
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) {
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
if (mPausingActivity != null) {
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
} else if (DEBUG_PAUSE) {
Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
}
if (pauseImmediately) {
completePauseLocked(false, resuming);
return false;
} else {
schedulePauseTimeout(prev);
return true;
}
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
if (resuming == null) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return false;
}
}
或许你有个疑问,既然这个地方直接return ture了,那ActivityStarter.startActivityUnchecked()调用是否就已经结束了呢;答案是肯定的。那你肯定又有疑问了,既然方法调用都结束了,那Activity到底是怎么启动的呢,因为目前只讲到了pause 之前应用的Activity,还没讲到启动Activity。要回答这个问题,这就看下pause Activity是怎么实现的了。先放张时序图,感兴趣的同学去跟一跟代码。

?上面的时序图主要分为两个步骤:
-
将前台应用A退入后台,实现的过程是在PauseActivityItem.excute()方法中调用ActivityThread.handlePauseActivity()方法; -
当应用A退入到后台后,将应用B显示到前台,实现过程是PauseActivityItem.postExcute()中调用ActivityTaskManagerService.activityPaused(),然后经过一系列方法调用,最后执行到了ActivityStack.resumeTopActivityInnerLocked()方法,这个方法我们前面讲过,只不过前面是在if (pausing && !resumeWhilePausing) 条件下return 了;而这个时候下会调用ActivitySupervisor.startSpecificActivityLocked()。startSpecificActivityLocked()会调用realStartActivityLocked()方法。
我们先看下startSpecificActivityLocked() 方法
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
knownToBeDead = true;
}
if (getKeyguardController().isKeyguardLocked()) {
r.notifyUnknownVisibilityLaunched();
}
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+ r.processName);
}
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
?App冷启动的过程会执行创建进程的过程,限于篇幅的原因,这里就不展开了,下次我们单独讲解。上面的时序图也省略了进程创建的过程,同样我们下次再补上。虽然这里省略了进程创建的过程,但是进程创建过后,也同样会调用realStartActivtiyLocked() 方法来继续执行启动Activity。我们看下realStartActivityLocked() 个方法:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
return true;
}
这个方法的核心是启动一个设置了LaunchActivityItem回调和ResumeActivityItem请求的事务。有了前面的经验我们知道,最终LauncherActivityItem和ResumeActivityItem的execute()方法会被执行,我们看下他们的execute()方法实现:
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken);
client.handleLaunchActivity(r, pendingActions, null );
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(token, true , mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
?方法很简单,分别调用了ActivityThread.handleLauncheActivity()、ActivityThread.handleResumeActivity();这两个方法最终会调用到Activity的onCreate()、onResume()方法。这个时候你可能就有疑问了,那onStart()方法呢,不是应该在onResume之前调用的吗。这个就要从TransactionExecutor.execute()说起,我们看下这个方法
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
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) {
return;
}
cycleToPath(r, lifecycleItem.getTargetState(), true , transaction);
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
@VisibleForTesting
public void cycleToPath(ActivityClientRecord r, int finish, ClientTransaction transaction) {
cycleToPath(r, finish, false , transaction);
}
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);
}
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 );
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false ,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false ,
false , 0 , mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, false ,
0 , mPendingActions, false ,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false ,
0 , false ,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false );
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
?代码中注释已经做了说明了,总结下就是在调用ResumeActivityItem.execute() 方法之前,会先执行cycleToPath() 判断Activity的起始状态和目标状态,如果后者大于前者,则需要执行两者之间的状态。至此冷启动情况下启动Activity就分析完了, 至于Activity启动后显示的过程可以参照下之前的文章《Activity UI显示流程分析》。当然还有很多细节没有展开,比如ActivityStack、TaskRecord的创建和更新,以及进程创建的过程;这写以后有机会再分享,大家也可以自己研究,文中的时序图可作为参考。
结束
?最后我们稍稍总结下,Activity启动过程主要分为两个过程:一是找到这个Activity(得到ActivityRecord对象);二是启动它,而启动过程又分为两种情况:一种在Activity栈中有Activity对应的ActivityRecord对象(这个会跟launchMode和launch flag有关),这种情况会走Activity的onNewIntent()方法;另一种是Activity栈中没有Activity对应的ActivityRecord,这种情况下又可分为多种子情况,但是我们不比纠结每种情况的细节;文中我们是分析了冷启动一个App的情况,虽然进程创建过程没有展开,但是后面Activity的启动流程还是一致的。
|