🤔startActivity到底发生了什么?-前端开发牛翰社区-编程开发-牛翰网

🤔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方法。
我们查看一下源码:

ActivityTaskManagerService
startActivityAsUser方法,展开查看

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

请登录后发表评论

    没有回复内容