startActivity到底发生了什么?

startActivity到底发生了什么?

大家好不好奇,我们平常使用的最多的startActivity这个方法底层到底是什么样子的?本篇文章就为大家来解密!
本文主要源码的位置如下:
frameworks/base/services/core/java/com/android/server/wm
我们先根据下面的图从宏观上看一下startActivity发生了什么.

一、App进程中

startActivity方法的调用链如下:
Activity中:
startActivity -> startActivityForResult -> mInstrumentation.execStartActivity -> ActivityTaskManager.getService().startActivity.
ActivityTaskManager.getService()是从单例对象中,通过binder跨进程调用拿到的是一个IActivityTaskManager, 它是ActivityTaskManagerService的一个代理对象, 然后调动的是其startActivity方法,然后后面的逻辑都是在系统进程完成的。
源码如下:

private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
	new Singleton<IActivityTaskManager>() {
	@Override
	protected IActivityTaskManager create() {
	final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
	return IActivityTaskManager.Stub.asInterface(b);
	}
};

二、系统进程中

startActivity快进程调用了ActivityTaskManagerServicestartActivityAsUser方法。
我们查看一下源码:

ActivityTaskManagerServicestartActivityAsUser方法,展开查看
private int startActivityAsUser(
	IApplicationThread caller, String callingPackage,
	@Nullable String callingFeatureId, Intent intent, String resolvedType,
	IBinder resultTo, String resultWho, int requestCode, int startFlags,
	ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
	
	final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
	assertPackageMatchesCallingUid(callingPackage);
	enforceNotIsolatedCaller("startActivityAsUser");
	if (isSdkSandboxActivityIntent(mContext, intent)) {
	SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
	SdkSandboxManagerLocal.class);
	sdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity(
	intent, Binder.getCallingUid(), callingPackage
	);
	}
	if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
	SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
	SdkSandboxManagerLocal.class);
	if (sdkSandboxManagerLocal == null) {
	throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
	+ " an activity from an SDK sandbox uid.");
	}
	sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
	}
	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)
	.setCallingFeatureId(callingFeatureId)
	.setResolvedType(resolvedType)
	.setResultTo(resultTo)
	.setResultWho(resultWho)
	.setRequestCode(requestCode)
	.setStartFlags(startFlags)
	.setProfilerInfo(profilerInfo)
	.setActivityOptions(opts)
	.setUserId(userId)
	.execute();
}

由源码可知,又调用了ActivityStartController对象的obtainStarter方法.
obtainStarter源码如下

ActivityStarter obtainStarter(Intent intent, String reason) {
	return mFactory
	.obtain().setIntent(intent).setReason(reason);
}

由源码可知通过链式调用返回了一个ActivityStarter对象,所以obtainStarter返回的ActivityStarter也通过链式调用最后执行到execute方法,我们查看下其源码:
ActivityStarter.java

int execute() {
	// Required for logging ContentOrFileUriEventReported in the finally block.
	String callerActivityName = null;
	ActivityRecord launchingRecord = null;
 try {
 onExecutionStarted();
 if (mRequest.intent != null) {
 // Refuse possible leaked file descriptors
 if (mRequest.intent.hasFileDescriptors()) {
 throw new IllegalArgumentException("File descriptors passed in Intent");
 }
 // Remove existing mismatch flag so it can be properly updated later
 mRequest.intent.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
 }
 final LaunchingState launchingState;
 synchronized (mService.mGlobalLock) {
 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
 final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
 ? Binder.getCallingUid() : mRequest.realCallingUid;
 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
 mRequest.intent, caller, callingUid);
 callerActivityName = caller != null ? caller.info.name : null;
 }
 if (mRequest.intent != null) {
 mRequest.componentSpecified |= mRequest.intent.getComponent() != null;
 }
 // If the caller hasn't already resolved the activity, we're willing
 // to do so here. If the caller is already holding the WM lock here,
 // and we need to check dynamic Uri permissions, then we're forced
 // to assume those permissions are denied to avoid deadlocking.
 if (mRequest.activityInfo == null) {
 mRequest.resolveActivity(mSupervisor);
 }
 // Add checkpoint for this shutdown or reboot attempt, so we can record the original
 // intent action and package name.
 if (mRequest.intent != null) {
 String intentAction = mRequest.intent.getAction();
 String callingPackage = mRequest.callingPackage;
 if (intentAction != null && callingPackage != null
 && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
 || Intent.ACTION_SHUTDOWN.equals(intentAction)
 || Intent.ACTION_REBOOT.equals(intentAction))) {
 ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
 }
 }
 int res = START_CANCELED;
 synchronized (mService.mGlobalLock) {
 final boolean globalConfigWillChange = mRequest.globalConfig != null
 && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
 final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
 if (rootTask != null) {
 rootTask.mConfigWillChange = globalConfigWillChange;
 }
 ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
 + "will change = %b", globalConfigWillChange);
 final long origId = Binder.clearCallingIdentity();
 try {
 res = resolveToHeavyWeightSwitcherIfNeeded();
 if (res != START_SUCCESS) {
 return res;
 }
 res = executeRequest(mRequest); // 1
 } finally {
 Binder.restoreCallingIdentity(origId);
 mRequest.logMessage.append(" result code=").append(res);
 Slog.i(TAG, mRequest.logMessage.toString());
 mRequest.logMessage.setLength(0);
 }
 if (globalConfigWillChange) {
 // If the caller also wants to switch to a new configuration, do so now.
 // This allows a clean switch, as we are waiting for the current activity
 // to pause (so we will not destroy it), and have not yet started the
 // next activity.
 mService.mAmInternal.enforceCallingPermission(
 android.Manifest.permission.CHANGE_CONFIGURATION,
 "updateConfiguration()");
 if (rootTask != null) {
 rootTask.mConfigWillChange = false;
 }
 ProtoLog.v(WM_DEBUG_CONFIGURATION,
 "Updating to new configuration after starting activity.");
 mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
 }
 // The original options may have additional info about metrics. The mOptions is not
 // used here because it may be cleared in setTargetRootTaskIfNeeded.
 final ActivityOptions originalOptions = mRequest.activityOptions != null
 ? mRequest.activityOptions.getOriginalOptions() : null;
 // Only track the launch time of activity that will be resumed.
 launchingRecord = mDoResume ? mLastStartActivityRecord : null;
 // If the new record is the one that started, a new activity has created.
 final boolean newActivityCreated = mStartActivity == launchingRecord;
 // Notify ActivityMetricsLogger that the activity has launched.
 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
 // WaitResult.
 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
 newActivityCreated, launchingRecord, originalOptions);
 if (mRequest.waitResult != null) {
 mRequest.waitResult.result = res;
 res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
 launchingState);
 }
 return getExternalResult(res);
 }
 } finally {
 // Notify UriGrantsManagerService that activity launch completed. Required for logging
 // the ContentOrFileUriEventReported message.
 mSupervisor.mService.mUgmInternal.notifyActivityLaunchRequestCompleted(
 mRequest.hashCode(),
 // isSuccessfulLaunch
 launchingRecord != null,
 // Intent action
 mRequest.intent != null ? mRequest.intent.getAction() : null,
 mRequest.realCallingUid,
 callerActivityName,
 // Callee UID
 mRequest.activityInfo != null
 ? mRequest.activityInfo.applicationInfo.uid : INVALID_UID,
 // Callee Activity name
 mRequest.activityInfo != null ? mRequest.activityInfo.name : null,
 // isStartActivityForResult
 launchingRecord != null && launchingRecord.resultTo != null);
 onExecutionComplete();
 }
}

位置1处是真正完成Activity启动流程的代码。
其源码如下:
ActivityStarter.java

/**
 * Executing activity start request and starts the journey of starting an activity. Here
 * begins with performing several preliminary checks. The normally activity launch flow will
 * go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
 */
private int executeRequest(Request request) {
	if (TextUtils.isEmpty(request.reason)) {
	throw new IllegalArgumentException("Need to specify a reason.");
	}
	mLastStartReason = request.reason;
	mLastStartActivityTimeMs = System.currentTimeMillis();
	final IApplicationThread caller = request.caller;
	Intent intent = request.intent;
	NeededUriGrants intentGrants = request.intentGrants;
	String resolvedType = request.resolvedType;
	ActivityInfo aInfo = request.activityInfo;
	ResolveInfo rInfo = request.resolveInfo;
	final IVoiceInteractionSession voiceSession = request.voiceSession;
	final IBinder resultTo = request.resultTo;
	String resultWho = request.resultWho;
	int requestCode = request.requestCode;
	int callingPid = request.callingPid;
	int callingUid = request.callingUid;
	String callingPackage = request.callingPackage;
	String callingFeatureId = request.callingFeatureId;
	final int realCallingPid = request.realCallingPid;
	final int realCallingUid = request.realCallingUid;
	final int startFlags = request.startFlags;
	final SafeActivityOptions options = request.activityOptions;
	Task inTask = request.inTask;
	TaskFragment inTaskFragment = request.inTaskFragment;
	int err = ActivityManager.START_SUCCESS;
	// Pull the optional Ephemeral Installer-only bundle out of the options early.
	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 = START_PERMISSION_DENIED;
	}
	}
	final int userId = aInfo != null && aInfo.applicationInfo != null
	? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
	final int launchMode = aInfo != null ? aInfo.launchMode : 0;
	if (err == ActivityManager.START_SUCCESS) {
	request.logMessage.append("START u").append(userId).append(" {")
	.append(intent.toShortString(true, true, true, false))
	.append("} with ").append(launchModeToString(launchMode))
	.append(" from uid ").append(callingUid);
	if (callingUid != realCallingUid
	&& realCallingUid != Request.DEFAULT_REAL_CALLING_UID) {
	request.logMessage.append(" (realCallingUid=").append(realCallingUid).append(")");
	}
	}
	ActivityRecord sourceRecord = null;
	ActivityRecord resultRecord = null;
	if (resultTo != null) {
	sourceRecord = ActivityRecord.isInAnyTask(resultTo);
	if (DEBUG_RESULTS) {
	Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
	}
	if (sourceRecord != null) {
	if (requestCode >= 0 && !sourceRecord.finishing) {
	resultRecord = sourceRecord;
	}
	}
	}
	final int launchFlags = intent.getFlags();
	if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
	// Transfer the result target from the source activity to the new one being started,
	// including any failures.
	if (requestCode >= 0) {
	SafeActivityOptions.abort(options);
	return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
	}
	resultRecord = sourceRecord.resultTo;
	if (resultRecord != null && !resultRecord.isInRootTaskLocked()) {
	resultRecord = null;
	}
	resultWho = sourceRecord.resultWho;
	requestCode = sourceRecord.requestCode;
	sourceRecord.resultTo = null;
	if (resultRecord != null) {
	resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
	}
	if (sourceRecord.launchedFromUid == callingUid) {
	// The new activity is being launched from the same uid as the previous activity
	// in the flow, and asking to forward its result back to the previous. In this
	// case the activity is serving as a trampoline between the two, so we also want
	// to update its launchedFromPackage to be the same as the previous activity.
	// Note that this is safe, since we know these two packages come from the same
	// uid; the caller could just as well have supplied that same package name itself
	// . This specifially deals with the case of an intent picker/chooser being
	// launched in the app flow to redirect to an activity picked by the user, where
	// we want the final activity to consider it to have been launched by the
	// previous app activity.
	callingPackage = sourceRecord.launchedFromPackage;
	callingFeatureId = sourceRecord.launchedFromFeatureId;
	}
	}
	if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
	// We couldn't find a class that can handle the given Intent.
	// That's the end of that!
	err = ActivityManager.START_INTENT_NOT_RESOLVED;
	}
	if (err == ActivityManager.START_SUCCESS && aInfo == null) {
	// We couldn't find the specific class specified in the Intent.
	err = ActivityManager.START_CLASS_NOT_FOUND;
	if (isArchivingEnabled()) {
	PackageArchiver packageArchiver = mService
	.getPackageManagerInternalLocked()
	.getPackageArchiver();
	if (packageArchiver.isIntentResolvedToArchivedApp(intent, mRequest.userId)) {
	err = packageArchiver
	.requestUnarchiveOnActivityStart(
	intent, callingPackage, mRequest.userId, realCallingUid);
	}
	}
	}
	if (err == ActivityManager.START_SUCCESS && sourceRecord != null
	&& sourceRecord.getTask().voiceSession != null) {
	// If this activity is being launched as part of a voice session, we need to ensure
	// that it is safe to do so. If the upcoming activity will also be part of the voice
	// session, we can only launch it if it has explicitly said it supports the VOICE
	// category, or it is a part of the calling app.
	if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
	&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
	try {
	intent.addCategory(Intent.CATEGORY_VOICE);
	if (!mService.getPackageManager().activitySupportsIntentAsUser(
	intent.getComponent(), intent, resolvedType, userId)) {
	Slog.w(TAG, "Activity being started in current voice task does not support "
	 + "voice: " + intent);
	err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
	}
	} catch (RemoteException e) {
	Slog.w(TAG, "Failure checking voice capabilities", e);
	err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
	}
	}
	}
	if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
	// If the caller is starting a new voice session, just make sure the target
	// is actually allowing it to run this way.
	try {
	if (!mService.getPackageManager().activitySupportsIntentAsUser(
	intent.getComponent(), intent, resolvedType, userId)) {
	Slog.w(TAG,
	 "Activity being started in new voice task does not support: " + intent);
	err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
	}
	} catch (RemoteException e) {
	Slog.w(TAG, "Failure checking voice capabilities", e);
	err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
	}
	}
	final Task resultRootTask = resultRecord == null
	? null : resultRecord.getRootTask();
	if (err != START_SUCCESS) {
	if (resultRecord != null) {
	resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
	null /* data */, null /* callerToken */, null /* dataGrants */);
	}
	SafeActivityOptions.abort(options);
	return err;
	}
	boolean abort;
	try {
	abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
	 requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
	 request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
	 resultRootTask);
	} catch (SecurityException e) {
	// Return activity not found for the explicit intent if the caller can't see the target
	// to prevent the disclosure of package existence.
	final Intent originalIntent = request.ephemeralIntent;
	if (originalIntent != null && (originalIntent.getComponent() != null
	 || originalIntent.getPackage() != null)) {
	final String targetPackageName = originalIntent.getComponent() != null
	? originalIntent.getComponent().getPackageName()
	: originalIntent.getPackage();
	if (mService.getPackageManagerInternalLocked()
	.filterAppAccess(targetPackageName, callingUid, userId)) {
	if (resultRecord != null) {
	resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
	RESULT_CANCELED, null /* data */, null /* callerToken */,
	null /* dataGrants */);
	}
	SafeActivityOptions.abort(options);
	return ActivityManager.START_CLASS_NOT_FOUND;
	}
	}
	throw e;
	}
	abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
	 callingPid, resolvedType, aInfo.applicationInfo);
	abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
	callingPackage);
	// Merge the two options bundles, while realCallerOptions takes precedence.
	ActivityOptions checkedOptions = options != null
	? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
	final BalVerdict balVerdict;
	if (!abort) {
	try {
	Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
	 "shouldAbortBackgroundActivityStart");
	BackgroundActivityStartController balController =
	mSupervisor.getBackgroundActivityLaunchController();
	balVerdict =
	balController.checkBackgroundActivityStart(
	callingUid,
	callingPid,
	callingPackage,
	realCallingUid,
	realCallingPid,
	callerApp,
	request.originatingPendingIntent,
	request.forcedBalByPiSender,
	resultRecord,
	intent,
	checkedOptions);
	request.logMessage.append(" (").append(balVerdict).append(")");
	} finally {
	Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
	}
	} else {
	// Sets ALLOW_BY_DEFAULT as default value as the activity launch will be aborted anyway.
	balVerdict = BalVerdict.ALLOW_BY_DEFAULT;
	}
	if (request.allowPendingRemoteAnimationRegistryLookup) {
	checkedOptions = mService.getActivityStartController()
	.getPendingRemoteAnimationRegistry()
	.overrideOptionsIfNeeded(callingPackage, checkedOptions);
	}
	if (mService.mController != null) {
	try {
	// The Intent we give to the watcher has the extra data stripped off, since it
	// can contain private information.
	Intent watchIntent = intent.cloneFilter();
	abort |= !mService.mController.activityStarting(watchIntent,
	aInfo.applicationInfo.packageName);
	} catch (RemoteException e) {
	mService.mController = null;
	}
	}
	final TaskDisplayArea suggestedLaunchDisplayArea =
	computeSuggestedLaunchDisplayArea(inTask, sourceRecord, checkedOptions);
	mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
	 callingFeatureId);
	if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
	 callingPid, callingUid, checkedOptions, suggestedLaunchDisplayArea)) {
	// activity start was intercepted, e.g. because the target user is currently in quiet
	// mode (turn off work) or the target application is suspended
	intent = mInterceptor.mIntent;
	rInfo = mInterceptor.mRInfo;
	aInfo = mInterceptor.mAInfo;
	resolvedType = mInterceptor.mResolvedType;
	inTask = mInterceptor.mInTask;
	callingPid = mInterceptor.mCallingPid;
	callingUid = mInterceptor.mCallingUid;
	checkedOptions = mInterceptor.mActivityOptions;
	// The interception target shouldn't get any permission grants
	// intended for the original destination
	intentGrants = null;
	}
	if (abort) {
	if (resultRecord != null) {
	resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
	null /* data */, null /* callerToken */, null /* dataGrants */);
	}
	// We pretend to the caller that it was really started, but they will just get a
	// cancel result.
	ActivityOptions.abort(checkedOptions);
	return START_ABORTED;
	}
	// If permissions need a review before any of the app components can run, we
	// launch the review activity and pass a pending intent to start the activity
	// we are to launching now after the review is completed.
	if (aInfo != null) {
	if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
	aInfo.packageName, userId)) {
	final IIntentSender target = mService.getIntentSenderLocked(
	ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
	callingUid, userId, null, null, 0, new Intent[]{intent},
	new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
	| PendingIntent.FLAG_ONE_SHOT, null);
	Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
	int flags = intent.getFlags();
	flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
	/*
 * Prevent reuse of review activity: Each app needs their own review activity. By
 * default activities launched with NEW_TASK or NEW_DOCUMENT try to reuse activities
 * with the same launch parameters (extras are ignored). Hence to avoid possible
 * reuse force a new activity via the MULTIPLE_TASK flag.
 *
 * Activities that are not launched with NEW_TASK or NEW_DOCUMENT are not re-used,
 * hence no need to add the flag in this case.
 */
	if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
	flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
	}
	newIntent.setFlags(flags);
	newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
	newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
	if (resultRecord != null) {
	newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
	}
	intent = newIntent;
	// The permissions review target shouldn't get any permission
	// grants intended for the original destination
	intentGrants = null;
	resolvedType = null;
	callingUid = realCallingUid;
	callingPid = realCallingPid;
	rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
	 computeResolveFilterUid(
	 callingUid, realCallingUid, request.filterCallingUid),
	 realCallingPid);
	aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
	null /*profilerInfo*/);
	if (DEBUG_PERMISSIONS_REVIEW) {
	final Task focusedRootTask =
	mRootWindowContainer.getTopDisplayFocusedRootTask();
	Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
	 true, false) + "} from uid " + callingUid + " on display "
	 + (focusedRootTask == null ? DEFAULT_DISPLAY
	 : focusedRootTask.getDisplayId()));
	}
	}
	}
	// If we have an ephemeral app, abort the process of launching the resolved intent.
	// Instead, launch the ephemeral installer. Once the installer is finished, it
	// starts either the intent we resolved here [on install error] or the ephemeral
	// app [on install success].
	if (rInfo != null && rInfo.auxiliaryInfo != null) {
	intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
	callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
	resolvedType = null;
	callingUid = realCallingUid;
	callingPid = realCallingPid;
	// The ephemeral installer shouldn't get any permission grants
	// intended for the original destination
	intentGrants = null;
	aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
	}
	// TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
	// Pending intent launched from systemui also depends on caller app
	if (callerApp == null && realCallingPid > 0) {
	final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
	if (wpc != null) {
	callerApp = wpc;
	}
	}
	final ActivityRecord r = new ActivityRecord.Builder(mService)
	.setCaller(callerApp)
	.setLaunchedFromPid(callingPid)
	.setLaunchedFromUid(callingUid)
	.setLaunchedFromPackage(callingPackage)
	.setLaunchedFromFeature(callingFeatureId)
	.setIntent(intent)
	.setResolvedType(resolvedType)
	.setActivityInfo(aInfo)
	.setConfiguration(mService.getGlobalConfiguration())
	.setResultTo(resultRecord)
	.setResultWho(resultWho)
	.setRequestCode(requestCode)
	.setComponentSpecified(request.componentSpecified)
	.setRootVoiceInteraction(voiceSession != null)
	.setActivityOptions(checkedOptions)
	.setSourceRecord(sourceRecord)
	.build();
	mLastStartActivityRecord = r;
	if (r.appTimeTracker == null && sourceRecord != null) {
	// If the caller didn't specify an explicit time tracker, we want to continue
	// tracking under any it has.
	r.appTimeTracker = sourceRecord.appTimeTracker;
	}
	// Only allow app switching to be resumed if activity is not a restricted background
	// activity and target app is not home process, otherwise any background activity
	// started in background task can stop home button protection mode.
	// As the targeted app is not a home process and we don't need to wait for the 2nd
	// activity to be started to resume app switching, we can just enable app switching
	// directly.
	WindowProcessController homeProcess = mService.mHomeProcess;
	boolean isHomeProcess = homeProcess != null
	&& aInfo.applicationInfo.uid == homeProcess.mUid;
	if (balVerdict.allows() && !isHomeProcess) {
	mService.resumeAppSwitches();
	}
	// Only do the create here since startActivityInner can abort. If it doesn't abort,
	// the requestStart will be sent in handleStartRequest.
	final Transition newTransition = r.mTransitionController.isShellTransitionsEnabled()
	? r.mTransitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
	// Because startActivity must run immediately, it can get combined with another
	// transition meaning it is no-longer independent. This is NOT desirable, but is the
	// only option for the time being.
	final boolean isIndependent = newTransition != null;
	final Transition transition = isIndependent ? newTransition
	: mService.getTransitionController().getCollectingTransition();
	// 1
	mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
	 request.voiceInteractor, startFlags, checkedOptions,
	 inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid, transition,
	 isIndependent);
	if (request.outActivity != null) {
	request.outActivity[0] = mLastStartActivityRecord;
	}
	return mLastStartActivityResult;
}

有文档注释可知:
startActivityUnchecked -> startActivityInner
startActivityUnchecked源码如下:
ActivityStarter.java

/**
 * Start an activity while most of preliminary checks has been done and caller has been
 * confirmed that holds necessary permissions to do so.
 * Here also ensures that the starting activity is removed if the start wasn't successful.
 */
private int startActivityUnchecked(
	final ActivityRecord r, ActivityRecord sourceRecord,
	IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
	int startFlags, ActivityOptions options, Task inTask,
	TaskFragment inTaskFragment,
	BalVerdict balVerdict,
	NeededUriGrants intentGrants, int realCallingUid, Transition transition,
	boolean isIndependentLaunch) {
	
	int result = START_CANCELED;
	final Task startedActivityRootTask;
	RemoteTransition remoteTransition = r.takeRemoteTransition();
	// Create a display snapshot as soon as possible.
	if (isIndependentLaunch && mRequest.freezeScreen) {
	final TaskDisplayArea tda = mLaunchParams.hasPreferredTaskDisplayArea()
	? mLaunchParams.mPreferredTaskDisplayArea
	: mRootWindowContainer.getDefaultTaskDisplayArea();
	final DisplayContent dc = mRootWindowContainer.getDisplayContentOrCreate(
	tda.getDisplayId());
	if (dc != null) {
	transition.collect(dc);
	transition.collectVisibleChange(dc);
	}
	}
	try {
	mService.deferWindowLayout();
	r.mTransitionController.collect(r);
	try {
	Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
	result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, // 1
	startFlags, options, inTask, inTaskFragment, balVerdict,
	intentGrants, realCallingUid);
	} catch (Exception ex) {
	Slog.e(TAG, "Exception on startActivityInner", ex);
	} finally {
	Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
	startedActivityRootTask = handleStartResult(r, options, result, isIndependentLaunch,
	remoteTransition, transition);
	}
	} finally {
	mService.continueWindowLayout();
	}
	postStartActivityProcessing(r, result, startedActivityRootTask);
	return result;
}

startActivityInner源码如下:
ActivityStarter.java

/**
 * Start an activity and determine if the activity should be adding to the top of an existing
 * task or delivered new intent to an existing activity. Also manipulating the activity task
 * onto requested or valid root-task/display.
 *
 * Note: This method should only be called from {@link #startActivityUnchecked}.
 */
// TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
@VisibleForTesting
int startActivityInner(
	final ActivityRecord r, ActivityRecord sourceRecord,
	IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
	int startFlags, ActivityOptions options, Task inTask,
	TaskFragment inTaskFragment, BalVerdict balVerdict,
	NeededUriGrants intentGrants, int realCallingUid) {
	
	setInitialState(r, options, inTask, inTaskFragment, startFlags, sourceRecord,
	voiceSession, voiceInteractor, balVerdict.getCode(), realCallingUid);
	computeLaunchingTaskFlags();
	mIntent.setFlags(mLaunchFlags);
	boolean dreamStopping = false;
	for (ActivityRecord stoppingActivity : mSupervisor.mStoppingActivities) {
	if (stoppingActivity.getActivityType()
	== WindowConfiguration.ACTIVITY_TYPE_DREAM) {
	dreamStopping = true;
	break;
	}
	}
	// Get top task at beginning because the order may be changed when reusing existing task.
	final Task prevTopRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
	final Task prevTopTask = prevTopRootTask != null ? prevTopRootTask.getTopLeafTask() : null;
	final boolean sourceActivityLaunchedFromBubble =
	sourceRecord != null && sourceRecord.getLaunchedFromBubble();
	// if the flag is enabled, allow reusing bubbled tasks only if the source activity is
	// bubbled.
	final boolean includeLaunchedFromBubble =
	Flags.onlyReuseBubbledTaskWhenLaunchedFromBubble()
	? sourceActivityLaunchedFromBubble : true;
	final Task reusedTask = resolveReusableTask(includeLaunchedFromBubble);
	// If requested, freeze the task list
	if (mOptions != null && mOptions.freezeRecentTasksReordering()
	&& mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
	&& !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
	mFrozeTaskList = true;
	mSupervisor.mRecentTasks.setFreezeTaskListReordering();
	}
	// Compute if there is an existing task that should be used for.
	final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
	final boolean newTask = targetTask == null;
	mTargetTask = targetTask;
	computeLaunchParams(r, sourceRecord, targetTask);
	// Check if starting activity on given task or on a new task is allowed.
	int startResult = isAllowedToStart(r, newTask, targetTask);
	if (startResult != START_SUCCESS) {
	if (r.resultTo != null) {
	r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED,
	 null /* data */, null /* callerToken */, null /* dataGrants */);
	}
	return startResult;
	}
	if (targetTask != null) {
	if (targetTask.getTreeWeight() > MAX_TASK_WEIGHT_FOR_ADDING_ACTIVITY) {
	Slog.e(TAG, "Remove " + targetTask + " because it has contained too many"
	 + " activities or windows (abort starting " + r
	 + " from uid=" + mCallingUid);
	targetTask.removeImmediately("bulky-task");
	return START_ABORTED;
	}
	// When running transient transition, the transient launch target should keep on top.
	// So disallow the transient hide activity to move itself to front, e.g. trampoline.
	if (!avoidMoveToFront() && (mService.mHomeProcess == null
	|| mService.mHomeProcess.mUid != realCallingUid)
	&& (prevTopTask != null && prevTopTask.isActivityTypeHomeOrRecents())
	&& r.mTransitionController.isTransientHide(targetTask)) {
	mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_LEGACY;
	}
	// If the activity is started by sending a pending intent and only its creator has the
	// privilege to allow BAL (its sender does not), avoid move it to the front. Only do
	// this when it is not a new task and not already been marked as avoid move to front.
	// Guarded by a flag: balDontBringExistingBackgroundTaskStackToFg
	if (balDontBringExistingBackgroundTaskStackToFg() && !avoidMoveToFront()
	&& balVerdict.onlyCreatorAllows()) {
	mCanMoveToFrontCode = MOVE_TO_FRONT_AVOID_PI_ONLY_CREATOR_ALLOWS;
	}
	mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask());
	}
	final ActivityRecord targetTaskTop = newTask
	? null : targetTask.getTopNonFinishingActivity();
	if (targetTaskTop != null) {
	// Removes the existing singleInstance activity in another task (if any) while
	// launching a singleInstance activity on sourceRecord's task.
	if (LAUNCH_SINGLE_INSTANCE == mLaunchMode && mSourceRecord != null
	&& targetTask == mSourceRecord.getTask()) {
	final ActivityRecord activity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info, false);
	if (activity != null && activity.getTask() != targetTask) {
	activity.destroyIfPossible("Removes redundant singleInstance");
	}
	}
	if (mLastStartActivityRecord != null) {
	targetTaskTop.mLaunchSourceType = mLastStartActivityRecord.mLaunchSourceType;
	}
	targetTaskTop.mTransitionController.collect(targetTaskTop);
	recordTransientLaunchIfNeeded(targetTaskTop);
	// Recycle the target task for this launch.
	startResult =
	recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants, balVerdict);
	if (startResult != START_SUCCESS) {
	return startResult;
	}
	} else {
	mAddingToTask = true;
	}
	// If the activity being launched is the same as the one currently at the top, then
	// we need to check if it should only be launched once.
	final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
	if (topRootTask != null) {
	startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
	if (startResult != START_SUCCESS) {
	return startResult;
	}
	}
	if (mTargetRootTask == null) {
	mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
	 mOptions);
	}
	if (newTask) {
	final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
	? mSourceRecord.getTask() : null;
	setNewTask(taskToAffiliate);
	} else if (mAddingToTask) {
	addOrReparentStartingActivity(targetTask, "adding to task");
	}
	// After activity is attached to task, but before actual start
	recordTransientLaunchIfNeeded(mLastStartActivityRecord);
	if (mDoResume) {
	if (!avoidMoveToFront()) {
	mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
	if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
	&& !dreamStopping) {
	// Launching underneath dream activity (fullscreen, always-on-top). Run the
	// launch--behind transition so the Activity gets created and starts
	// in visible state.
	mLaunchTaskBehind = true;
	r.mLaunchTaskBehind = true;
	}
	} else {
	logPIOnlyCreatorAllowsBAL();
	}
	}
	mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, mStartActivity.getUriPermissionsLocked());
	if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
	// we need to resolve resultTo to a uid as grantImplicitAccess deals explicitly in UIDs
	final PackageManagerInternal pmInternal =
	mService.getPackageManagerInternalLocked();
	final int resultToUid = pmInternal.getPackageUid(
	mStartActivity.resultTo.info.packageName, 0 /* flags */,
	mStartActivity.mUserId);
	pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
	 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
	 resultToUid /*visible*/, true /*direct*/);
	} else if (mStartActivity.mShareIdentity) {
	final PackageManagerInternal pmInternal =
	mService.getPackageManagerInternalLocked();
	pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
	 UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
	 r.launchedFromUid /*visible*/, true /*direct*/);
	}
	final Task startedTask = mStartActivity.getTask();
	if (newTask) {
	EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId,
	 startedTask.getRootTaskId(), startedTask.getDisplayId());
	}
	mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);
	mStartActivity.getTaskFragment().clearLastPausedActivity();
	mRootWindowContainer.startPowerModeLaunchIfNeeded(
	false /* forceSend */, mStartActivity);
	final boolean isTaskSwitch = startedTask != prevTopTask;
	mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
	mOptions, sourceRecord);
	if (mDoResume) {
	final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
	if (!mTargetRootTask.isTopActivityFocusable()
	|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
	&& 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.
	// Passing {@code null} as the start parameter ensures all activities are made
	// visible.
	mTargetRootTask.ensureActivitiesVisible(null /* starting */);
	// 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.
	mTargetRootTask.mDisplayContent.executeAppTransition();
	} else {
	// If the target root-task was not previously focusable (previous top running
	// activity on that root-task was not visible) then any prior calls to move the
	// root-task to the will not update the focused root-task. If starting the new
	// activity now allows the task root-task to be focusable, then ensure that we
	// now update the focused root-task accordingly.
	if (mTargetRootTask.isTopActivityFocusable()
	&& !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
	if (!avoidMoveToFront()) {
	mTargetRootTask.moveToFront("startActivityInner");
	} else {
	logPIOnlyCreatorAllowsBAL();
	}
	}
	mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch); // 1
	}
	}
	mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
	// Update the recent tasks list immediately when the activity starts
	mSupervisor.mRecentTasks.add(startedTask);
	mSupervisor.handleNonResizableTaskIfNeeded(startedTask, mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
	// If Activity's launching into PiP, move the mStartActivity immediately to pinned mode.
	// Note that mStartActivity and source should be in the same Task at this point.
	if (mOptions != null && mOptions.isLaunchIntoPip()
	&& sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
	&& balVerdict.allows()) {
	mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity, sourceRecord, "launch-into-pip", null /* bounds */);
	}
	mSupervisor.getBackgroundActivityLaunchController()
	.onNewActivityLaunched(mStartActivity); // mStartActivity 是 ActivityStarter对象的ActivityRecord类型的成员变量
	return START_SUCCESS;
}

源码中
mStartActivityActivityStarter对象的ActivityRecord类型的成员变量.
mSupervisorActivityTaskSupervisor类型的对象,管理任务栈逻辑.
mRootWindowContainerRootWindowContainer类型的对象.
我们看下RootWindowContainer类型的对象的resumeFocusedTasksTopActivities方法的源码:
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

boolean resumeFocusedTasksTopActivities(
	Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
	boolean deferPause) {
	
	if (!mTaskSupervisor.readyToResume()) {
	return false;
	}
	boolean result = false;
	if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea() || getTopDisplayFocusedRootTask() == targetRootTask)) {
	result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions, deferPause);
	}
	for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
	final DisplayContent display = getChildAt(displayNdx);
	final boolean curResult = result;
	boolean[] resumedOnDisplay = new boolean[1];
	final ActivityRecord topOfDisplay = display.topRunningActivity();
	display.forAllRootTasks(rootTask -> {
	final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
	if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
	return;
	}
	if (rootTask == targetRootTask) {
	// Simply update the result for targetRootTask because the targetRootTask
	// had already resumed in above. We don't want to resume it again,
	// especially in some cases, it would cause a second launch failure
	// if app process was dead.
	resumedOnDisplay[0] |= curResult;
	return;
	}
	if (topRunningActivity.isState(RESUMED) && topRunningActivity == topOfDisplay) {
	// Kick off any lingering app transitions form the MoveTaskToFront operation,
	// but only consider the top activity on that display.
	rootTask.executeAppTransition(targetOptions);
	} else {
	resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
	}
	});
	result |= resumedOnDisplay[0];
	if (!resumedOnDisplay[0]) {
	// In cases when there are no valid activities (e.g. device just booted or launcher
	// crashed) it's possible that nothing was resumed on a display. Requesting resume
	// of top activity in focused root task explicitly will make sure that at least home
	// activity is started and resumed, and no recursion occurs.
	final Task focusedRoot = display.getFocusedRootTask();
	if (focusedRoot != null) {
	result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions, false /* skipPause */); // 1
	} else if (targetRootTask == null) {
	result |= resumeHomeActivity(null /* prev */, "no-focusable-task", display.getDefaultTaskDisplayArea());
	}
	}
	}
	return result;
}

focusedRootTask类型的对象,接下来查看方法resumeTopActivityUncheckedLocked的源码:
frameworks/base/services/core/java/com/android/server/wm/Task.java

/**
 * Ensure that the top activity in the root task is resumed.
 *
 * @param prev The previously resumed activity, for when in the process
 * of pausing; can be null to call from elsewhere.
 * @param options Activity options.
 * @param deferPause When {@code true}, this will not pause back tasks.
 *
 * @return Returns true if something is being resumed, or false if
 * nothing happened.
 *
 * NOTE: It is not safe to call this method directly as it can cause an activity in a
 * non-focused root task to be resumed.
 * Use {@link RootWindowContainer#resumeFocusedTasksTopActivities} to resume the
 * right activity for the current system state.
 */
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) {
	if (mInResumeTopActivity) {
	// Don't even start recursing.
	return false;
	}
	boolean someActivityResumed = false;
	try {
	// Protect against recursion.
	mInResumeTopActivity = true;
	if (isLeafTask()) {
	if (isFocusableAndVisible()) {
	someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause); // 1
	}
	} else {
	int idx = mChildren.size() - 1;
	while (idx >= 0) {
	final Task child = (Task) getChildAt(idx--);
	if (!child.isTopActivityFocusable()) {
	continue;
	}
	if (child.getVisibility(null /* starting */)
	!= TASK_FRAGMENT_VISIBILITY_VISIBLE) {
	if (child.topRunningActivity() == null) {
	// Skip the task if no running activity and continue resuming next task.
	continue;
	}
	// Otherwise, assuming everything behind this task should also be invisible.
	break;
	}
	someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options, deferPause);
	// Doing so in order to prevent IndexOOB since hierarchy might changes while
	// resuming activities, for example dismissing split-screen while starting
	// non-resizeable activity.
	if (idx >= mChildren.size()) {
	idx = mChildren.size() - 1;
	}
	}
	}
	// When resuming the top activity, it may be necessary to pause the top activity (for
	// example, returning to the lock screen. We suppress the normal pause logic in
	// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
	// end. We call the {@link ActivityTaskSupervisor#checkReadyForSleepLocked} again here
	// to ensure any necessary pause logic occurs. In the case where the Activity will be
	// shown regardless of the lock screen, the call to
	// {@link ActivityTaskSupervisor#checkReadyForSleepLocked} is skipped.
	final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
	if (next == null || !next.canTurnScreenOn()) {
	checkReadyForSleep();
	}
	} finally {
	mInResumeTopActivity = false;
	}
	return someActivityResumed;
}

继续看Task对象的resumeTopActivityInnerLocked方法:

@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
	 boolean deferPause) {
	if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
	// Not ready yet!
	return false;
	}
	final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
	if (topActivity == null) {
	// There are no activities left in this task, let's look somewhere else.
	return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
	}
	final boolean[] resumed = new boolean[1];
	final TaskFragment topFragment = topActivity.getTaskFragment();
	resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause); // 1
	forAllLeafTaskFragments(f -> {
	if (topFragment == f) {
	return;
	}
	if (!f.canBeResumed(null /* starting */)) {
	return;
	}
	resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
	}, true);
	return resumed[0];
}

TaskFragmentresumeTopActivity源码如下:
frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java

final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options, boolean skipPause) {
	ActivityRecord next = topRunningActivity(true /* focusableOnly */);
	if (next == null || !next.canResumeByCompat()) {
	return false;
	}
	next.delayedResume = false;
	if (!skipPause && !mRootWindowContainer.allPausedActivitiesComplete()) {
	// If we aren't skipping pause, then we have to wait for currently pausing activities.
	ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: some activity pausing.");
	return false;
	}
	final TaskDisplayArea taskDisplayArea = getDisplayArea();
	// If the top activity is the resumed one, nothing to do.
	if (mResumedActivity == next && next.isState(RESUMED)
	&& taskDisplayArea.allResumedActivitiesComplete()) {
	// Ensure the visibility gets updated before execute app transition.
	taskDisplayArea.ensureActivitiesVisible(null /* starting */, true /* notifyClients */);
	// Make sure we have executed any pending transitions, since there
	// should be nothing left to do at this point.
	executeAppTransition(options);
	// In a multi-resumed environment, like in a freeform device, the top
	// activity can be resumed, but it might not be the focused app.
	// Set focused app when top activity is resumed. However, we shouldn't do it for a
	// same task because it can break focused state. (e.g. activity embedding)
	if (taskDisplayArea.inMultiWindowMode() && taskDisplayArea.mDisplayContent != null) {
	final ActivityRecord focusedApp = taskDisplayArea.mDisplayContent.mFocusedApp;
	if (focusedApp == null || focusedApp.getTask() != next.getTask()) {
	taskDisplayArea.mDisplayContent.setFocusedApp(next);
	}
	}
	ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity "
	 + "resumed %s", next);
	return false;
	}
	// If we are sleeping, and there is no resumed activity, and the top activity is paused,
	// well that is the state we want.
	if (mLastPausedActivity == next && shouldSleepOrShutDownActivities()) {
	// Make sure we have executed any pending transitions, since there
	// should be nothing left to do at this point.
	executeAppTransition(options);
	ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Going to sleep and"
	 + " all paused");
	return false;
	}
	// Make sure that the user who owns this activity is started. If not,
	// we will just leave it as is because someone should be bringing
	// another user's activities to the top of the stack.
	if (!mAtmService.mAmInternal.hasStartedUserState(next.mUserId)) {
	Slog.w(TAG, "Skipping resume of top activity " + next
	 + ": user " + next.mUserId + " is stopped");
	return false;
	}
	// The activity may be waiting for stop, but that is no longer
	// appropriate for it.
	mTaskSupervisor.mStoppingActivities.remove(next);
	if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
	mTaskSupervisor.setLaunchSource(next.info.applicationInfo.uid);
	ActivityRecord lastResumed = null;
	final Task lastFocusedRootTask = taskDisplayArea.getLastFocusedRootTask();
	if (lastFocusedRootTask != null && lastFocusedRootTask != getRootTaskFragment().asTask()) {
	// So, why aren't we using prev here??? See the param comment on the method. prev
	// doesn't represent the last resumed activity. However, the last focus stack does if
	// it isn't null.
	lastResumed = lastFocusedRootTask.getTopResumedActivity();
	}
	boolean pausing = !skipPause && taskDisplayArea.pauseBackTasks(next);
	if (mResumedActivity != null) {
	ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity);
	pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
	next, "resumeTopActivity");
	}
	if (pausing) {
	ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: need to"
	 + " start pausing");
	// At this point we want to put the upcoming activity's process
	// at the top of the LRU list, since we know we will be needing it
	// very soon and it would be a waste to let it get killed if it
	// happens to be sitting towards the end.
	if (next.attachedToProcess()) {
	next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
	 true /* activityChange */, false /* updateOomAdj */,
	 false /* addPendingTopUid */);
	} else if (!next.isProcessRunning()) {
	// Since the start-process is asynchronous, if we already know the process of next
	// activity isn't running, we can start the process earlier to save the time to wait
	// for the current activity to be paused.
	final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
	mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
	 isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
	 : HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
	}
	if (lastResumed != null) {
	lastResumed.setWillCloseOrEnterPip(true);
	}
	return true;
	} else if (mResumedActivity == next && next.isState(RESUMED)
	 && taskDisplayArea.allResumedActivitiesComplete()) {
	// It is possible for the activity to be resumed when we paused back stacks above if the
	// next activity doesn't have to wait for pause to complete.
	// So, nothing else to-do except:
	// Make sure we have executed any pending transitions, since there
	// should be nothing left to do at this point.
	executeAppTransition(options);
	ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity resumed "
	 + "(dontWaitForPause) %s", next);
	return true;
	}
	// If the most recent activity was noHistory but was only stopped rather
	// than stopped+finished because the device went to sleep, we need to make
	// sure to finish it as we're making a new activity topmost.
	if (shouldSleepActivities()) {
	mTaskSupervisor.finishNoHistoryActivitiesIfNeeded(next);
	}
	if (prev != null && prev != next && next.nowVisible) {
	// The next activity is already visible, so hide the previous
	// activity's windows right now so we can show the new one ASAP.
	// We only do this if the previous is finishing, which should mean
	// it is on top of the one being resumed so hiding it quickly
	// is good. Otherwise, we want to do the normal route of allowing
	// the resumed activity to be shown so we can decide if the
	// previous should actually be hidden depending on whether the
	// new one is found to be full-screen or not.
	if (prev.finishing) {
	prev.setVisibility(false);
	if (DEBUG_SWITCH) {
	Slog.v(TAG_SWITCH, "Not waiting for visible to hide: " + prev
	 + ", nowVisible=" + next.nowVisible);
	}
	} else {
	if (DEBUG_SWITCH) {
	Slog.v(TAG_SWITCH, "Previous already visible but still waiting to hide: " + prev
	 + ", nowVisible=" + next.nowVisible);
	}
	}
	}
	try {
	mTaskSupervisor.getActivityMetricsLogger()
	.notifyBeforePackageUnstopped(next.packageName);
	mAtmService.getPackageManagerInternalLocked().notifyComponentUsed(
	next.packageName, next.mUserId,
	next.packageName, next.toString()); /* TODO: Verify if correct userid */
	} catch (IllegalArgumentException e) {
	Slog.w(TAG, "Failed trying to unstop package "
	 + next.packageName + ": " + e);
	}
	// We are starting up the next activity, so tell the window manager
	// that the previous one will be hidden soon. This way it can know
	// to ignore it when computing the desired screen orientation.
	boolean anim = true;
	final DisplayContent dc = taskDisplayArea.mDisplayContent;
	if (prev != null) {
	if (prev.finishing) {
	if (DEBUG_TRANSITION) {
	Slog.v(TAG_TRANSITION, "Prepare close transition: prev=" + prev);
	}
	if (mTaskSupervisor.mNoAnimActivities.contains(prev)) {
	anim = false;
	dc.prepareAppTransition(TRANSIT_NONE);
	} else {
	dc.prepareAppTransition(TRANSIT_CLOSE);
	}
	prev.setVisibility(false);
	} else {
	if (DEBUG_TRANSITION) {
	Slog.v(TAG_TRANSITION, "Prepare open transition: prev=" + prev);
	}
	if (mTaskSupervisor.mNoAnimActivities.contains(next)) {
	anim = false;
	dc.prepareAppTransition(TRANSIT_NONE);
	} else {
	dc.prepareAppTransition(TRANSIT_OPEN, next.mLaunchTaskBehind ? TRANSIT_FLAG_OPEN_BEHIND : 0);
	}
	}
	} else {
	if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
	if (mTaskSupervisor.mNoAnimActivities.contains(next)) {
	anim = false;
	dc.prepareAppTransition(TRANSIT_NONE);
	} else {
	dc.prepareAppTransition(TRANSIT_OPEN);
	}
	}
	if (anim) {
	next.applyOptionsAnimation();
	} else {
	next.abortAndClearOptionsAnimation();
	}
	mTaskSupervisor.mNoAnimActivities.clear();
	if (next.attachedToProcess()) {
	if (DEBUG_SWITCH) {
	Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.mAppStopped
	 + " visibleRequested=" + next.isVisibleRequested());
	}
	// If the previous activity is translucent, force a visibility update of
	// the next activity, so that it's added to WM's opening app list, and
	// transition animation can be set up properly.
	// For example, pressing Home button with a translucent activity in focus.
	// Launcher is already visible in this case. If we don't add it to opening
	// apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
	// TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
	final boolean lastActivityTranslucent = inMultiWindowMode()
	|| mLastPausedActivity != null && !mLastPausedActivity.occludesParent();
	// This activity is now becoming visible.
	if (!next.isVisibleRequested() || next.mAppStopped || lastActivityTranslucent) {
	next.app.addToPendingTop();
	next.setVisibility(true);
	}
	// schedule launch ticks to collect information about slow apps.
	next.startLaunchTickingLocked();
	ActivityRecord lastResumedActivity =
	lastFocusedRootTask == null ? null
	: lastFocusedRootTask.getTopResumedActivity();
	final ActivityRecord.State lastState = next.getState();
	mAtmService.updateCpuStats();
	ProtoLog.v(WM_DEBUG_STATES, "Moving to RESUMED: %s (in existing)", next);
	next.setState(RESUMED, "resumeTopActivity");
	// Activity should also be visible if set mLaunchTaskBehind to true (see
	// ActivityRecord#shouldBeVisibleIgnoringKeyguard()).
	if (shouldBeVisible(next)) {
	// We have special rotation behavior when here is some active activity that
	// requests specific orientation or Keyguard is locked. Make sure all activity
	// visibilities are set correctly as well as the transition is updated if needed
	// to get the correct rotation behavior. Otherwise the following call to update
	// the orientation may cause incorrect configurations delivered to client as a
	// result of invisible window resize.
	// TODO: Remove this once visibilities are set correctly immediately when
	// starting an activity.
	final int originalRelaunchingCount = next.mPendingRelaunchCount;
	mRootWindowContainer.ensureVisibilityAndConfig(next, mDisplayContent,
	 false /* deferResume */);
	if (next.mPendingRelaunchCount > originalRelaunchingCount) {
	// The activity is scheduled to relaunch, then ResumeActivityItem will be also
	// included (see ActivityRecord#relaunchActivityLocked) if it should resume.
	next.completeResumeLocked();
	return true;
	}
	}
	try {
	final IApplicationThread appThread = next.app.getThread();
	// Deliver all pending results.
	final ArrayList<ResultInfo> a = next.results;
	if (a != null) {
	final int size = a.size();
	if (!next.finishing && size > 0) {
	if (DEBUG_RESULTS) {
	Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a);
	}
	final ActivityResultItem item = new ActivityResultItem(next.token, a);
	mAtmService.getLifecycleManager().scheduleTransactionItem(appThread, item);
	}
	}
	if (next.newIntents != null) {
	final NewIntentItem item =
	new NewIntentItem(next.token, next.newIntents, true /* resume */);
	mAtmService.getLifecycleManager().scheduleTransactionItem(appThread, item);
	}
	// Well the app will no longer be stopped.
	// Clear app token stopped state in window manager if needed.
	next.notifyAppResumed();
	EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
	 next.getTask().mTaskId, next.shortComponentName);
	mAtmService.getAppWarningsLocked().onResumeActivity(next);
	final int topProcessState = mAtmService.mTopProcessState;
	next.app.setPendingUiCleanAndForceProcessStateUpTo(topProcessState);
	next.abortAndClearOptionsAnimation();
	final ResumeActivityItem resumeActivityItem = new ResumeActivityItem(
	next.token, topProcessState, dc.isNextTransitionForward(),
	next.shouldSendCompatFakeFocus());
	mAtmService.getLifecycleManager().scheduleTransactionItem(
	appThread, resumeActivityItem);
	ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);
	} catch (Exception e) {
	// Whoops, need to restart this activity!
	ProtoLog.v(WM_DEBUG_STATES, "Resume failed; resetting state to %s: "
	 + "%s", 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 && lastFocusedRootTask != null
	 && lastFocusedRootTask.isTopRootTaskInDisplayArea()) {
	next.showStartingWindow(false /* taskSwitch */);
	}
	mTaskSupervisor.startSpecificActivity(next, true, false);
	return true;
	}
	next.completeResumeLocked();
	} else {
	// Whoops, need to restart this activity!
	if (!next.hasBeenLaunched) {
	next.hasBeenLaunched = true;
	} else {
	if (SHOW_APP_STARTING_PREVIEW) {
	next.showStartingWindow(false /* taskSwich */);
	}
	if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
	}
	ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Restarting %s", next);
	mTaskSupervisor.startSpecificActivity(next, true, true); // 1
	}
	return true;
}

代码1处ActivityTaskSupervisor对象调用startSpecificActivity方法启动Activity,源码如下:

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
	// Is this activity's application already running?
	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); // 1
	return;
	} catch (RemoteException e) {
	Slog.w(TAG, "Exception when starting activity "
	 + r.intent.getComponent().flattenToShortString(), e);
	}
	// If a dead object exception was thrown -- fall through to
	// restart the application.
	knownToBeDead = true;
	// Remove the process record so it won't be considered as alive.
	mService.mProcessNames.remove(wpc.mName, wpc.mUid);
	mService.mProcessMap.remove(wpc.getPid());
	} else if (ActivityTaskManagerService.isSdkSandboxActivityIntent(
	mService.mContext, r.intent)) {
	Slog.e(TAG, "Abort sandbox activity launching as no sandbox process to host it.");
	r.finishIfPossible("No sandbox process for the activity", false /* oomAdj */);
	r.launchFailed = true;
	r.detachFromProcess();
	return;
	}
	r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
	final boolean isTop = andResume && r.isTopRunningActivity();
	mService.startProcessAsync(r, knownToBeDead, isTop,
	 isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
	 : HostingRecord.HOSTING_TYPE_ACTIVITY);
}

代码1处ActivityTaskSupervisor对象调用realStartActivityLocked方法启动Activity,源码如下:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException {
	if (!mRootWindowContainer.allPausedActivitiesComplete()) {
	// While there are activities pausing we skipping starting any new activities until
	// pauses are complete. NOTE: that we also do this for activities that are starting in
	// the paused state because they will first be resumed then paused on the client side.
	ProtoLog.v(WM_DEBUG_STATES,
	 "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
	 r);
	return false;
	}
	final Task task = r.getTask();
	if (andResume) {
	// Try pausing the existing resumed activity in the Task if any.
	if (task.pauseActivityIfNeeded(r, "realStart")) {
	return false;
	}
	final TaskFragment taskFragment = r.getTaskFragment();
	if (taskFragment != null && taskFragment.getResumedActivity() != null) {
	if (taskFragment.startPausing(mUserLeaving, false /* uiSleeping */, r,
	 "realStart")) {
	return false;
	}
	}
	}
	final Task rootTask = task.getRootTask();
	beginDeferResume();
	// The LaunchActivityItem also contains process configuration, so the configuration change
	// from WindowProcessController#setProcess can be deferred. The major reason is that if
	// the activity has FixedRotationAdjustments, it needs to be applied with configuration.
	// In general, this reduces a binder transaction if process configuration is changed.
	proc.pauseConfigurationDispatch();
	try {
	// schedule launch ticks to collect information about slow apps.
	r.startLaunchTickingLocked();
	r.lastLaunchTime = SystemClock.uptimeMillis();
	r.setProcess(proc);
	// Ensure activity is allowed to be resumed after process has set.
	if (andResume && !r.canResumeByCompat()) {
	andResume = false;
	}
	r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
	// Have the window manager re-evaluate the orientation of the screen based on the new
	// activity order. Note that as a result of this, it can call back into the activity
	// manager with a new orientation. We don't care about that, because the activity is
	// not currently running so we are just restarting it anyway.
	if (checkConfig) {
	// Deferring resume here because we're going to launch new activity shortly.
	// We don't want to perform a redundant launch of the same record while ensuring
	// configurations and trying to resume top activity of focused root task.
	mRootWindowContainer.ensureVisibilityAndConfig(r, r.mDisplayContent, true /* deferResume */);
	}
	if (mKeyguardController.checkKeyguardVisibility(r) && r.allowMoveToFront()) {
	// We only set the visibility to true if the activity is not being launched in
	// background, and is allowed to be visible based on keyguard state. This avoids
	// setting this into motion in window manager that is later cancelled due to later
	// calls to ensure visible activities that set visibility back to false.
	r.setVisibility(true);
	}
	final int applicationInfoUid =
	(r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
	if ((r.mUserId != proc.mUserId) || (r.info.applicationInfo.uid != applicationInfoUid)) {
	Slog.wtf(TAG,
	 "User ID for activity changing for " + r
	 + " appInfo.uid=" + r.info.applicationInfo.uid
	 + " info.ai.uid=" + applicationInfoUid
	 + " old=" + r.app + " new=" + proc);
	}
	// Send the controller to client if the process is the first time to launch activity.
	// So the client can save binder transactions of getting the controller from activity
	// task manager service.
	final IActivityClientController activityClientController =
	proc.hasEverLaunchedActivity() ? null : mService.mActivityClientController;
	r.launchCount++;
	if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
	final LockTaskController lockTaskController = mService.getLockTaskController();
	if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
	|| task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
	|| (task.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED
	&& lockTaskController.getLockTaskModeState()
	== LOCK_TASK_MODE_LOCKED)) {
	lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */);
	}
	try {
	if (!proc.hasThread()) {
	throw new RemoteException();
	}
	List<ResultInfo> results = null;
	List<ReferrerIntent> newIntents = null;
	if (andResume) {
	// We don't need to deliver new intents and/or set results if activity is going
	// to pause immediately after launch.
	results = r.results;
	newIntents = r.newIntents;
	}
	if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
	 "Launching: " + r + " savedState=" + r.getSavedState()
	 + " with results=" + results + " newIntents=" + newIntents
	 + " andResume=" + andResume);
	EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
	task.mTaskId, r.shortComponentName);
	updateHomeProcessIfNeeded(r);
	mService.getPackageManagerInternalLocked().notifyPackageUse(
	r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
	mService.getAppWarningsLocked().onStartActivity(r);
	final Configuration procConfig = proc.prepareConfigurationForLaunchingActivity();
	final Configuration overrideConfig = r.getMergedOverrideConfiguration();
	r.setLastReportedConfiguration(procConfig, overrideConfig);
	final ActivityWindowInfo activityWindowInfo = r.getActivityWindowInfo();
	r.setLastReportedActivityWindowInfo(activityWindowInfo);
	logIfTransactionTooLarge(r.intent, r.getSavedState());
	final TaskFragment organizedTaskFragment = r.getOrganizedTaskFragment();
	if (organizedTaskFragment != null) {
	// Sending TaskFragmentInfo to client to ensure the info is updated before
	// the activity creation.
	mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
	organizedTaskFragment);
	}
	// Create activity launch transaction.
	final boolean isTransitionForward = r.isTransitionForward();
	final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
	final int deviceId = getDeviceIdForDisplayId(r.getDisplayId());
	final LaunchActivityItem launchActivityItem = new LaunchActivityItem(r.token, r.intent, System.identityHashCode(r), r.info,
	 procConfig, overrideConfig, deviceId,
	 r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
	 proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
	 results, newIntents, r.takeSceneTransitionInfo(), isTransitionForward,
	 proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
	 r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken,
	 r.initialCallerInfoAccessToken, activityWindowInfo);
	// Set desired final state.
	final ActivityLifecycleItem lifecycleItem;
	if (andResume) {
	lifecycleItem = new ResumeActivityItem(r.token, isTransitionForward,
	 r.shouldSendCompatFakeFocus());
	} else if (r.isVisibleRequested()) {
	lifecycleItem = new PauseActivityItem(r.token);
	} else {
	lifecycleItem = new StopActivityItem(r.token);
	}
	// Schedule transaction.
	if (shouldDispatchLaunchActivityItemIndependently(r.info.packageName, r.getUid())) {
	// LaunchActivityItem has @UnsupportedAppUsage usages.
	// Guard with targetSDK on Android 15+.
	// To not bundle the transaction, dispatch the pending before schedule new
	// transaction.
	mService.getLifecycleManager().dispatchPendingTransaction(proc.getThread());
	}
	mService.getLifecycleManager().scheduleTransactionAndLifecycleItems(
	proc.getThread(), launchActivityItem, lifecycleItem,
	// Immediately dispatch the transaction, so that if it fails, the server can
	// restart the process and retry now.
	true /* shouldDispatchImmediately */); // 1
	if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) {
	// If the seq is increased, there should be something changed (e.g. registered
	// activity configuration).
	proc.setLastReportedConfiguration(procConfig);
	}
	if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
	&& mService.mHasHeavyWeightFeature) {
	// This may be a heavy-weight process! Note that the package manager will ensure
	// that only activity can run in the main process of the .apk, which is the only
	// thing that will be considered heavy-weight.
	if (proc.mName.equals(proc.mInfo.packageName)) {
	if (mService.mHeavyWeightProcess != null
	&& mService.mHeavyWeightProcess != proc) {
	Slog.w(TAG, "Starting new heavy weight process " + proc
	 + " when already running "
	 + mService.mHeavyWeightProcess);
	}
	mService.setHeavyWeightProcess(r);
	}
	}
	} catch (RemoteException e) {
	if (r.launchFailed) {
	// This is the second time we failed -- finish activity and give up.
	Slog.e(TAG, "Second failure launching "
	 + r.intent.getComponent().flattenToShortString() + ", giving up", e);
	proc.appDied("2nd-crash");
	r.finishIfPossible("2nd-crash", false /* oomAdj */);
	return false;
	}
	// This is the first time we failed -- restart process and
	// retry.
	r.launchFailed = true;
	r.detachFromProcess();
	throw e;
	}
	} finally {
	endDeferResume();
	proc.resumeConfigurationDispatch();
	}
	r.launchFailed = false;
	// TODO(lifecycler): Resume or pause requests are done as part of launch transaction,
	// so updating the state should be done accordingly.
	if (andResume && readyToResume()) {
	// As part of the process of launching, ActivityThread also performs
	// a resume.
	r.setState(RESUMED, "realStartActivityLocked");
	r.completeResumeLocked();
	} else if (r.isVisibleRequested()) {
	// This activity is not starting in the resumed state... which should look like we asked
	// it to pause+stop (but remain visible), and it has done so and reported back the
	// current icicle and other state.
	ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s "
	 + "(starting in paused state)", r);
	r.setState(PAUSED, "realStartActivityLocked");
	mRootWindowContainer.executeAppTransitionForAllDisplay();
	} else {
	// This activity is starting while invisible, so it should be stopped.
	r.setState(STOPPING, "realStartActivityLocked");
	}
	// Perform OOM scoring after the activity state is set, so the process can be updated with
	// the latest state.
	proc.onStartActivity(mService.mTopProcessState, r.info); // 2
	// Launch the new version setup screen if needed. We do this -after-
	// launching the initial activity (that is, home), so that it can have
	// a chance to initialize itself while in the background, making the
	// switch back to it faster and look better.
	if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) {
	mService.getActivityStartController().startSetupActivity(); // 3
	}
	// Update any services we are bound to that might care about whether
	// their client may have activities.
	if (r.app != null) {
	r.app.updateServiceConnectionActivities();
	}
	return true;
}

在1处真正启动Activity,
mService是一个ActivityTaskManagerService类型的对象。
mService.getLifecycleManager()方法返回的是一个ClientLifecycleManager类型的对象。
scheduleTransactionAndLifecycleItems源码如下:
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client,
	 @NonNull ClientTransactionItem transactionItem,
	 @NonNull ActivityLifecycleItem lifecycleItem,
	 boolean shouldDispatchImmediately) throws RemoteException {
	// Wait until RootWindowContainer#performSurfacePlacementNoTrace to dispatch all pending
	// transactions at once.
	final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
	clientTransaction.addTransactionItem(transactionItem);
	clientTransaction.addTransactionItem(lifecycleItem);
	onClientTransactionItemScheduled(clientTransaction, shouldDispatchImmediately);
}

scheduleTransactionAndLifecycleItems方法又调用了onClientTransactionItemScheduled方法,其源码如下:
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

/** Must only be called with WM lock. */
private void onClientTransactionItemScheduled(
	@NonNull ClientTransaction clientTransaction,
	boolean shouldDispatchImmediately) throws RemoteException {
	if (shouldDispatchImmediately || shouldDispatchPendingTransactionsImmediately()) {
	// Dispatch the pending transaction immediately.
	mPendingTransactions.remove(clientTransaction.getClient().asBinder());
	scheduleTransaction(clientTransaction);
	}
}
/**
 * Schedules a transaction, which may consist of multiple callbacks and a lifecycle request.
 * @param transaction A sequence of client transaction items.
 * @throws RemoteException
 *
 * @see ClientTransaction
 */
@VisibleForTesting
void scheduleTransaction(@NonNull ClientTransaction transaction) throws RemoteException {
	final IApplicationThread client = transaction.getClient();
	try {
	transaction.schedule(); // 1
	} catch (RemoteException e) {
	Slog.w(TAG, "Failed to deliver transaction for " + client + "\ntransaction=" + transaction);
	throw e;
	}
}

transactionClientTransaction的源码如下:
frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

/**
 * 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.scheduleTransaction(this);
}

mClientIApplicationThread代理对象
frameworks/base/core/java/android/app/IApplicationThread.aidl

void scheduleTransaction(in ClientTransaction transaction);

则服务端进程调用链完成,现在回到App进程中。
ApplicationThreadActivityThread的内部类,我们来看下scheduleTransaction方法的源码。
frameworks/base/core/java/android/app/ActivityThread.java

/**
 * This manages the execution of the main thread in an
 * application process, scheduling and executing activities,
 * broadcasts, and other operations on it as the activity
 * manager requests.
 *
 * {@hide}
 */
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
	private class ApplicationThread extends IApplicationThread.Stub{
	@Override
	public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
	ActivityThread.this.scheduleTransaction(transaction); // 1
	}
	}
	
	// 真正的实现方法
	void sendMessage(int what, Object obj) {
	sendMessage(what, obj, 0, 0, false);
	}
	private void sendMessage(int what, Object obj, int arg1) {
	sendMessage(what, obj, arg1, 0, false);
	}
	private void sendMessage(int what, Object obj, int arg1, int arg2) {
	sendMessage(what, obj, arg1, arg2, false);
	}
	private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
	if (DEBUG_MESSAGES) {
	Slog.v(TAG,
	 "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
	}
	Message msg = Message.obtain();
	msg.what = what;
	msg.obj = obj;
	msg.arg1 = arg1;
	msg.arg2 = arg2;
	if (async) {
	msg.setAsynchronous(true);
	}
	mH.sendMessage(msg); // 2
	}
}

1处方法调用了ClientTransactionHandler对象的scheduleTransaction方法,其源码如下:
frameworks/base/core/java/android/app/ClientTransactionHandler.java

// Schedule phase related logic and handlers.
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
	transaction.preExecute(this);
	sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

如代码2处,
ClientTransactionHandler对象的sendMessage方法在ActivityThread中实现,最终调用了,ActivityThread的内部类H类型的对象mHsendMessage方法。我们来看一下EXECUTE_TRANSACTION常量对应的逻辑源码:
frameworks/base/core/java/android/app/ActivityThread.java

case EXECUTE_TRANSACTION:
	final ClientTransaction transaction = (ClientTransaction) msg.obj;
	final ClientTransactionListenerController controller =
	ClientTransactionListenerController.getInstance();
	controller.onClientTransactionStarted();
	try {
	mTransactionExecutor.execute(transaction); // 1
	} finally {
	controller.onClientTransactionFinished();
	}
	break;

private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
由源码可知mTransactionExecutor是一个TransactionExecutor类型的对象,其execute方法源码如下:
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

/**
 * 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(@NonNull ClientTransaction transaction) {
	if (DEBUG_RESOLVER) {
	Slog.d(TAG, tId(transaction) + "Start resolving transaction");
	Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
	}
	Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "clientTransactionExecuted");
	try {
	executeTransactionItems(transaction); // 1
	} catch (Exception e) {
	Slog.e(TAG, "Failed to execute the transaction: "
	 + transactionToString(transaction, mTransactionHandler));
	throw e;
	} finally {
	Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
	}
	mPendingActions.clear();
	if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
/** Cycles through all transaction items and execute them at proper times. */
@VisibleForTesting
public void executeTransactionItems(@NonNull ClientTransaction transaction) {
	final List<ClientTransactionItem> items = transaction.getTransactionItems();
	final int size = items.size();
	for (int i = 0; i < size; i++) {
	final ClientTransactionItem item = items.get(i);
	if (item.isActivityLifecycleItem()) {
	executeLifecycleItem(transaction, (ActivityLifecycleItem) item); // 2
	} else {
	executeNonLifecycleItem(transaction, item,
	shouldExcludeLastLifecycleState(items, i));
	}
	}
}
private void executeLifecycleItem(@NonNull ClientTransaction transaction,
	 @NonNull ActivityLifecycleItem lifecycleItem) {
	final IBinder token = lifecycleItem.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) {
	if (mTransactionHandler.getActivitiesToBeDestroyed().get(token) == lifecycleItem) {
	// Always cleanup for destroy item.
	lifecycleItem.postExecute(mTransactionHandler, mPendingActions);
	}
	// 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); // 3
	// Execute the final transition with proper parameters.
	lifecycleItem.execute(mTransactionHandler, mPendingActions); 
	lifecycleItem.postExecute(mTransactionHandler, mPendingActions);
}
/**
 * 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,
	 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); // 4
}
/** Transition the client through previously initialized state sequence. */
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: // 5
	mTransactionHandler.handleLaunchActivity(r, mPendingActions,
	 Context.DEVICE_ID_INVALID, null /* customIntent */);
	break;
	case ON_START:
	mTransactionHandler.handleStartActivity(r, mPendingActions,
	null /* sceneTransitionInfo */);
	break;
	case ON_RESUME:
	mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
	 r.isForward, false /* shouldSendCompatFakeFocus */,
	 "LIFECYCLER_RESUME_ACTIVITY");
	break;
	case ON_PAUSE:
	mTransactionHandler.handlePauseActivity(r, false /* finished */,
	false /* userLeaving */,
	false /* autoEnteringPip */, mPendingActions,
	"LIFECYCLER_PAUSE_ACTIVITY");
	break;
	case ON_STOP:
	mTransactionHandler.handleStopActivity(r,
	 mPendingActions, false /* finalStateRequest */,
	 "LIFECYCLER_STOP_ACTIVITY");
	break;
	case ON_DESTROY:
	mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
	 false /* getNonConfigInstance */,
	 "performLifecycleSequence. cycling to:" + path.get(size - 1));
	break;
	case ON_RESTART:
	mTransactionHandler.performRestartActivity(r, false /* start */);
	break;
	default:
	throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
	}
	}
}

代码5处执行了mTransactionHandler.handleLaunchActivity()方法,
mTransactionHandlerlientTransactionHandler类型的对象,其方法handleLaunchActivity源码如下所示:
frameworks/base/core/java/android/app/ClientTransactionHandler.java

public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r, PendingTransactionActions pendingActions, int deviceId, Intent customIntent);

最终是由其子类ActivityThread实现,其源码如下:
frameworks/base/core/java/android/app/ActivityThread.java

/**
 * Extended implementation of activity launch. Used when server requests a launch or relaunch.
 */
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
	 PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
	// If we are getting ready to gc after going to the background, well
	// we are back active so skip it.
	unscheduleGcIdler();
	mSomeActivitiesChanged = true;
	if (r.profilerInfo != null) {
	mProfiler.setProfiler(r.profilerInfo);
	mProfiler.startProfiling();
	}
	// Make sure we are running with the most recent config and resource paths.
	applyPendingApplicationInfoChanges(r.activityInfo.packageName);
	mConfigurationController.handleConfigurationChanged(null, null);
	updateDeviceIdForNonUIContexts(deviceId);
	if (localLOGV) Slog.v(
	TAG, "Handling launch of " + r);
	// Initialize before creating the activity
	if (ThreadedRenderer.sRendererEnabled
	&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
	HardwareRenderer.preload();
	}
	WindowManagerGlobal.initialize();
	// Hint the GraphicsEnvironment that an activity is launching on the process.
	GraphicsEnvironment.hintActivityLaunch();
	final Activity a = performLaunchActivity(r, customIntent); // 1
	if (a != null) {
	r.createdConfig = new Configuration(mConfigurationController.getConfiguration());
	reportSizeConfigurations(r);
	if (!r.activity.mFinished && pendingActions != null) {
	pendingActions.setOldState(r.state);
	pendingActions.setRestoreInstanceState(true);
	pendingActions.setCallOnPostCreate(true);
	}
	// Trigger ActivityWindowInfo callback if first launch or change from relaunch.
	handleActivityWindowInfoChanged(r);
	} else {
	// If there was an error, for any reason, tell the activity manager to stop us.
	ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
	null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
	}
	return a;
}
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	ActivityInfo aInfo = r.activityInfo;
	if (getInstrumentation() != null
	&& getInstrumentation().getContext() != null
	&& getInstrumentation().getContext().getApplicationInfo() != null
	&& getInstrumentation().isSdkSandboxAllowedToStartActivities()) {
	// Activities launched from CTS-in-sandbox tests use a customized ApplicationInfo. See
	// also {@link SdkSandboxManagerLocal#getSdkSandboxApplicationInfoForInstrumentation}.
	r.packageInfo =
	getPackageInfo(
	getInstrumentation().getContext().getApplicationInfo(),
	mCompatibilityInfo,
	Context.CONTEXT_INCLUDE_CODE);
	} else if (r.packageInfo == null) {
	r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo,
	 Context.CONTEXT_INCLUDE_CODE);
	}
	ComponentName component = r.intent.getComponent();
	if (component == null) {
	component = r.intent.resolveActivity(
	mInitialApplication.getPackageManager());
	r.intent.setComponent(component);
	}
	if (r.activityInfo.targetActivity != null) {
	component = new ComponentName(r.activityInfo.packageName,
	 r.activityInfo.targetActivity);
	}
	boolean isSandboxActivityContext =
	sandboxActivitySdkBasedContext()
	&& SdkSandboxActivityAuthority.isSdkSandboxActivityIntent(
	mSystemContext, r.intent);
	boolean isSandboxedSdkContextUsed = false;
	ContextImpl activityBaseContext;
	if (isSandboxActivityContext) {
	activityBaseContext = createBaseContextForSandboxActivity(r);
	if (activityBaseContext == null) {
	// Failed to retrieve the SDK based sandbox activity context, falling back to the
	// app based context.
	activityBaseContext = createBaseContextForActivity(r);
	} else {
	isSandboxedSdkContextUsed = true;
	}
	} else {
	activityBaseContext = createBaseContextForActivity(r);
	}
	Activity activity = null;
	try {
	java.lang.ClassLoader cl;
	if (isSandboxedSdkContextUsed) {
	// In case of sandbox activity, the context refers to the an SDK with no visibility
	// on the SandboxedActivity java class, the App context should be used instead.
	cl = activityBaseContext.getApplicationContext().getClassLoader();
	} else {
	cl = activityBaseContext.getClassLoader();
	}
	activity = mInstrumentation.newActivity(
	cl, component.getClassName(), r.intent); // 2
	StrictMode.incrementExpectedActivityCount(activity.getClass());
	r.intent.setExtrasClassLoader(cl);
	r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
	 activityBaseContext.getAttributionSource());
	if (r.state != null) {
	r.state.setClassLoader(cl);
	}
	} catch (Exception e) {
	if (!mInstrumentation.onException(activity, e)) {
	throw new RuntimeException(
	"Unable to instantiate activity " + component
	+ ": " + e.toString(), e);
	}
	}
	try {
	Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
	if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
	if (localLOGV) Slog.v(
	TAG, r + ": app=" + app
	+ ", appName=" + app.getPackageName()
	+ ", pkg=" + r.packageInfo.getPackageName()
	+ ", comp=" + r.intent.getComponent().toShortString()
	+ ", dir=" + r.packageInfo.getAppDir());
	// updatePendingActivityConfiguration() reads from mActivities to update
	// ActivityClientRecord which runs in a different thread. Protect modifications to
	// mActivities to avoid race.
	synchronized (mResourcesManager) {
	mActivities.put(r.token, r);
	}
	if (activity != null) {
	CharSequence title =
	r.activityInfo.loadLabel(activityBaseContext.getPackageManager());
	Configuration config =
	new Configuration(mConfigurationController.getCompatConfiguration());
	if (r.overrideConfig != null) {
	config.updateFrom(r.overrideConfig);
	}
	if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
	+ r.activityInfo.name + " with config " + config);
	Window window = null;
	if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
	window = r.mPendingRemoveWindow;
	r.mPendingRemoveWindow = null;
	r.mPendingRemoveWindowManager = null;
	}
	// Activity resources must be initialized with the same loaders as the
	// application context.
	activityBaseContext.getResources().addLoaders(
	app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
	activityBaseContext.setOuterContext(activity);
	activity.attach(activityBaseContext, this, getInstrumentation(), r.token,
	r.ident, app, r.intent, r.activityInfo, title, r.parent,
	r.embeddedID, r.lastNonConfigurationInstances, config,
	r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
	r.assistToken, r.shareableActivityToken, r.initialCallerInfoAccessToken);
	if (customIntent != null) {
	activity.mIntent = customIntent;
	}
	r.lastNonConfigurationInstances = null;
	checkAndBlockForNetworkAccess();
	activity.mStartedActivity = false;
	int theme = r.activityInfo.getThemeResource();
	if (theme != 0) {
	activity.setTheme(theme);
	}
	if (r.mSceneTransitionInfo != null) {
	activity.mSceneTransitionInfo = r.mSceneTransitionInfo;
	r.mSceneTransitionInfo = null;
	}
	activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
	activity.mCalled = false;
	// Assigning the activity to the record before calling onCreate() allows
	// ActivityThread#getActivity() lookup for the callbacks triggered from
	// ActivityLifecycleCallbacks#onActivityCreated() or
	// ActivityLifecycleCallback#onActivityPostCreated().
	r.activity = activity;
	if (r.isPersistable()) {
	mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
	} else {
	mInstrumentation.callActivityOnCreate(activity, r.state); // 1
	}
	if (!activity.mCalled) {
	throw new SuperNotCalledException(
	"Activity " + r.intent.getComponent().toShortString() +
	" did not call through to super.onCreate()");
	}
	r.mLastReportedWindowingMode = config.windowConfiguration.getWindowingMode();
	}
	r.setState(ON_CREATE);
	} catch (SuperNotCalledException e) {
	throw e;
	} catch (Exception e) {
	if (!mInstrumentation.onException(activity, e)) {
	throw new RuntimeException(
	"Unable to start activity " + component
	+ ": " + e.toString(), e);
	}
	}
	return activity;
}

代码2处mInstrumentation是一个Instrumentation类型的对象,其调用了newActivity方法,其源码如下:
frameworks/base/core/java/android/app/Instrumentation.java

public Activity newActivity(Class<?> clazz, Context context, 
	IBinder token, Application application, Intent intent, ActivityInfo info, 
	CharSequence title, Activity parent, String id,
	Object lastNonConfigurationInstance) throws InstantiationException,
IllegalAccessException {
	Activity activity = (Activity)clazz.newInstance();
	ActivityThread aThread = null;
	// Activity.attach expects a non-null Application Object.
	if (application == null) {
	application = new Application();
	}
	activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
	info, title, parent, id,
	(Activity.NonConfigurationInstances)lastNonConfigurationInstance,
	new Configuration(), null /* referrer */, null /* voiceInteractor */,
	null /* window */, null /* activityCallback */, null /* assistToken */,
	null /* shareableActivityToken */, null /* initialCallerInfoAccessToken */);
	return activity;
}

代码1处调用了ActivityonCreate方法,
frameworks/base/core/java/android/app/Instrumentation.java

/**
 * Perform calling of an activity's {@link Activity#onCreate}
 * method. The default implementation simply calls through to that method.
 *
 * @param activity The activity being created.
 * @param icicle The previously frozen state (or null) to pass through to onCreate().
 */
public void callActivityOnCreate(Activity activity, Bundle icicle) {
	prePerformCreate(activity);
	activity.performCreate(icicle); // 1
	postPerformCreate(activity);
}

1处代码最终调用了Activity对象的onCreate方法,其源码如下:

@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
 final void performCreate(Bundle icicle, PersistableBundle persistentState) {
 if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performCreate:"
 + mComponent.getClassName());
 }
 dispatchActivityPreCreated(icicle);
 mCanEnterPictureInPicture = true;
 // initialize mIsInMultiWindowMode and mIsInPictureInPictureMode before onCreate
 final int windowingMode = getResources().getConfiguration().windowConfiguration
 .getWindowingMode();
 mIsInMultiWindowMode = inMultiWindowMode(windowingMode);
 mIsInPictureInPictureMode = windowingMode == WINDOWING_MODE_PINNED;
 mShouldDockBigOverlays = getResources().getBoolean(R.bool.config_dockBigOverlayWindows);
 restoreHasCurrentPermissionRequest(icicle);
 final long startTime = SystemClock.uptimeMillis();
 if (persistentState != null) {
 onCreate(icicle, persistentState);
 } else {
 onCreate(icicle); // 1
 }
 final long duration = SystemClock.uptimeMillis() - startTime;
 EventLogTags.writeWmOnCreateCalled(mIdent, getComponentName().getClassName(),
 "performCreate", duration);
 mActivityTransitionState.readState(icicle);
 mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
 com.android.internal.R.styleable.Window_windowNoDisplay, false);
 mFragments.dispatchActivityCreated();
 mActivityTransitionState.setEnterSceneTransitionInfo(this, getSceneTransitionInfo());
 dispatchActivityPostCreated(icicle);
 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
 }

至此从startActivtyActivity对象的onCreate方法执行的调用链全部分析完成。

有什么不足的地方还望大家批评指正,提出宝贵意见,我一定慢慢完善。?


关联文章
// TODO
1. 启动一个未启动的App进程的Activity会发生什么?
2. 在LauncherActivity界面点击应用图标会发生什么?

作者:爱情丶眨眼而去原文地址:https://www.cnblogs.com/zshsboke/p/18679838/startActivity01

%s 个评论

要回复文章请先登录注册