startActivity流程(API 29):
Activity.java

@Overridepublic void startActivity(Intent intent, @Nullable Bundle options) {if (options != null) {startActivityForResult(intent, -1, options);} else {// Note we want to go through this call for compatibility with// applications that may have overridden the method.startActivityForResult(intent, -1);}}
 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {if (mParent == null) {options = transferSpringboardActivityOptions(options);Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());}if (requestCode >= 0) {mStartedActivity = true;}cancelInputsAndStartExitTransition(options);} else {if (options != null) {mParent.startActivityFromChild(this, intent, requestCode, options);} else {mParent.startActivityFromChild(this, intent, requestCode);}}}

Instrumentation.java

 @UnsupportedAppUsagepublic ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread;Uri referrer = target != null ? target.onProvideReferrer() : null;if (referrer != null) {intent.putExtra(Intent.EXTRA_REFERRER, referrer);}if (mActivityMonitors != null) {synchronized (mSync) {final int N = mActivityMonitors.size();for (int i=0; i<N; i++) {final ActivityMonitor am = mActivityMonitors.get(i);ActivityResult result = null;if (am.ignoreMatchingSpecificIntents()) {result = am.onStartActivity(intent);}if (result != null) {am.mHits++;return result;} else if (am.match(who, null, intent)) {am.mHits++;if (am.isBlocking()) {return requestCode >= 0 ? am.getResult() : null;}break;}}}}try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);int result = ActivityTaskManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;}

ActivityManagerService.java

@Overridepublic int startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {return mActivityTaskManager.startActivity(caller, callingPackage, intent, resolvedType,resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);}//权限检查@Overridepublic final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,bOptions, userId);}//WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {return mActivityTaskManager.startActivityAndWait(caller, callingPackage, intent,resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,bOptions, userId);}

ActivityTaskManagerService.java

 @Overridepublic final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {final WaitResult res = new WaitResult();synchronized (mGlobalLock) {enforceNotIsolatedCaller("startActivityAndWait");userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),userId, "startActivityAndWait");// TODO: Switch to user app stacks here.getActivityStartController().obtainStarter(intent, "startActivityAndWait").setCaller(caller).setCallingPackage(callingPackage).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setActivityOptions(bOptions).setMayWait(userId).setProfilerInfo(profilerInfo).setWaitResult(res).execute(); }return res;}

ActivityStartController.java

  /*** @return A starter to configure and execute starting an activity. It is valid until after*         {@link ActivityStarter#execute} is invoked. At that point, the starter should be*         considered invalid and no longer modified or used.*/ActivityStarter obtainStarter(Intent intent, String reason) {return mFactory.obtain().setIntent(intent).setReason(reason);}

ActivityStarter.java

 /*** Starts an activity based on the request parameters provided earlier.* @return The starter result.* ActivityTaskManagerService调用了该方法  setMayWait()   mRequest.mayWait = true;*/int execute() {try {// TODO(b/64750076): Look into passing request directly to these methods to allow// for transactional diffs and preprocessing.if (mRequest.mayWait) {return startActivityMayWait( ...);} else {return startActivity(...);}} finally {onExecutionComplete();}}
 private int startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, int requestRealCallingPid, int requestRealCallingUid,Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,int userId, TaskRecord inTask, String reason,boolean allowPendingRemoteAnimationRegistryLookup,PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {// Refuse possible leaked file descriptorsif (intent != null && intent.hasFileDescriptors()) {throw new IllegalArgumentException("File descriptors passed in Intent");}mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);boolean componentSpecified = intent.getComponent() != null;final int realCallingPid = requestRealCallingPid != Request.DEFAULT_REAL_CALLING_PID? requestRealCallingPid: Binder.getCallingPid();final int realCallingUid = requestRealCallingUid != Request.DEFAULT_REAL_CALLING_UID? requestRealCallingUid: Binder.getCallingUid();int callingPid;if (callingUid >= 0) {callingPid = -1;} else if (caller == null) {callingPid = realCallingPid;callingUid = realCallingUid;} else {callingPid = callingUid = -1;}// Save a copy in case ephemeral needs itfinal Intent ephemeralIntent = new Intent(intent);// Don't modify the client's object!intent = new Intent(intent);if (componentSpecified&& !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)&& !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())&& !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())&& mService.getPackageManagerInternalLocked().isInstantAppInstallerComponent(intent.getComponent())) {// intercept intents targeted directly to the ephemeral installer the// ephemeral installer should never be started with a raw Intent; instead// adjust the intent so it looks like a "normal" instant app launchintent.setComponent(null /*component*/);componentSpecified = false;}ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,0 /* matchFlags */,computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));if (rInfo == null) {UserInfo userInfo = mSupervisor.getUserInfo(userId);if (userInfo != null && userInfo.isManagedProfile()) {// Special case for managed profiles, if attempting to launch non-cryto aware// app in a locked managed profile from an unlocked parent allow it to resolve// as user will be sent via confirm credentials to unlock the profile.UserManager userManager = UserManager.get(mService.mContext);boolean profileLockedAndParentUnlockingOrUnlocked = false;long token = Binder.clearCallingIdentity();try {UserInfo parent = userManager.getProfileParent(userId);profileLockedAndParentUnlockingOrUnlocked = (parent != null)&& userManager.isUserUnlockingOrUnlocked(parent.id)&& !userManager.isUserUnlockingOrUnlocked(userId);} finally {Binder.restoreCallingIdentity(token);}if (profileLockedAndParentUnlockingOrUnlocked) {rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,PackageManager.MATCH_DIRECT_BOOT_AWARE| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));}}}// Collect information about the target of the Intent.//查找目标Activity的相关信息ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);synchronized (mService.mGlobalLock) {final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();stack.mConfigWillChange = globalConfig != null&& mService.getGlobalConfiguration().diff(globalConfig) != 0;if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,"Starting activity when config will change = " + stack.mConfigWillChange);final long origId = Binder.clearCallingIdentity();if (aInfo != null &&(aInfo.applicationInfo.privateFlags& ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&mService.mHasHeavyWeightFeature) {//判断目标Activity所属进程是不是重量级的,如果当前系统已经存在的重量级进程不是即将启动的这个,那么就要给Intent重新赋值if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {final WindowProcessController heavy = mService.mHeavyWeightProcess;if (heavy != null && (heavy.mInfo.uid != aInfo.applicationInfo.uid|| !heavy.mName.equals(aInfo.processName))) {int appCallingUid = callingUid;if (caller != null) {WindowProcessController callerApp =mService.getProcessController(caller);if (callerApp != null) {appCallingUid = callerApp.mInfo.uid;} else {Slog.w(TAG, "Unable to find app for caller " + caller+ " (pid=" + callingPid + ") when starting: "+ intent.toString());SafeActivityOptions.abort(options);return ActivityManager.START_PERMISSION_DENIED;}}IIntentSender target = mService.getIntentSenderLocked(ActivityManager.INTENT_SENDER_ACTIVITY, "android",appCallingUid, userId, null, null, 0, new Intent[] { intent },new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT| PendingIntent.FLAG_ONE_SHOT, null);//重新赋值Intent newIntent = new Intent();if (requestCode >= 0) {// Caller is requesting a result.newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);}newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,new IntentSender(target));heavy.updateIntentForHeavyWeightActivity(newIntent);newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,aInfo.packageName);newIntent.setFlags(intent.getFlags());newIntent.setClassName("android",HeavyWeightSwitcherActivity.class.getName());intent = newIntent;resolvedType = null;caller = null;callingUid = Binder.getCallingUid();callingPid = Binder.getCallingPid();componentSpecified = true;rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,0 /* matchFlags */, computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));aInfo = rInfo != null ? rInfo.activityInfo : null;if (aInfo != null) {aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);}}}}final ActivityRecord[] outRecord = new ActivityRecord[1];int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,allowBackgroundActivityStart);Binder.restoreCallingIdentity(origId);if (stack.mConfigWillChange) {// 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()");stack.mConfigWillChange = false;if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,"Updating to new configuration after starting activity.");mService.updateConfigurationLocked(globalConfig, null, false);}// Notify ActivityMetricsLogger that the activity has launched. ActivityMetricsLogger// will then wait for the windows to be drawn and populate WaitResult.//如果outResultmSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);if (outResult != null) {outResult.result = res;final ActivityRecord r = outRecord[0];switch(res) {case START_SUCCESS: {mSupervisor.mWaitingActivityLaunched.add(outResult);do {try {mService.mGlobalLock.wait();} catch (InterruptedException e) {}} while (outResult.result != START_TASK_TO_FRONT&& !outResult.timeout && outResult.who == null);if (outResult.result == START_TASK_TO_FRONT) {res = START_TASK_TO_FRONT;}break;}case START_DELIVERED_TO_TOP: {outResult.timeout = false;outResult.who = r.mActivityComponent;outResult.totalTime = 0;break;}case START_TASK_TO_FRONT: {outResult.launchState =r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD;// ActivityRecord may represent a different activity, but it should not be// in the resumed state.if (r.nowVisible && r.isState(RESUMED)) {outResult.timeout = false;outResult.who = r.mActivityComponent;outResult.totalTime = 0;} else {final long startTimeMs = SystemClock.uptimeMillis();mSupervisor.waitActivityVisible(r.mActivityComponent, outResult, startTimeMs);// Note: the timeout variable is not currently not ever set.do {try {mService.mGlobalLock.wait();} catch (InterruptedException e) {}} while (!outResult.timeout && outResult.who == null);}break;}}}return res;}}
 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,SafeActivityOptions options,boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);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 = ActivityManager.START_PERMISSION_DENIED;}}final int userId = aInfo != null && aInfo.applicationInfo != null? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;if (err == ActivityManager.START_SUCCESS) {Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)+ "} from uid " + callingUid);}ActivityRecord sourceRecord = null;ActivityRecord resultRecord = null;if (resultTo != null) {sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,"Will send result to " + resultTo + " " + sourceRecord);if (sourceRecord != null) {if (requestCode >= 0 && !sourceRecord.finishing) {resultRecord = sourceRecord;}}}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.isInStackLocked()) {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;}}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.// Also the end of the line.err = ActivityManager.START_CLASS_NOT_FOUND;}if (err == ActivityManager.START_SUCCESS && sourceRecord != null&& sourceRecord.getTaskRecord().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().activitySupportsIntent(intent.getComponent(), intent, resolvedType)) {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().activitySupportsIntent(intent.getComponent(),intent, resolvedType)) {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 ActivityStack resultStack = resultRecord == null? null : resultRecord.getActivityStack();if (err != START_SUCCESS) {if (resultRecord != null) {resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);}SafeActivityOptions.abort(options);return err;}boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,inTask != null, callerApp, resultRecord, resultStack);abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,callingPid, resolvedType, aInfo.applicationInfo);abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,callingPackage);boolean restrictedBgActivity = false;if (!abort) {try {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"shouldAbortBackgroundActivityStart");restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,originatingPendingIntent, allowBackgroundActivityStart, intent);} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}// Merge the two options bundles, while realCallerOptions takes precedence.ActivityOptions checkedOptions = options != null? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;if (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;}}mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,callingUid, checkedOptions)) {// activity start was intercepted, e.g. because the target user is currently in quiet// mode (turn off work) or the target application is suspendedintent = mInterceptor.mIntent;rInfo = mInterceptor.mRInfo;aInfo = mInterceptor.mAInfo;resolvedType = mInterceptor.mResolvedType;inTask = mInterceptor.mInTask;callingPid = mInterceptor.mCallingPid;callingUid = mInterceptor.mCallingUid;checkedOptions = mInterceptor.mActivityOptions;}if (abort) {if (resultRecord != null) {resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,RESULT_CANCELED, null);}// 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)) {IIntentSender target = mService.getIntentSenderLocked(ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,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;resolvedType = null;callingUid = realCallingUid;callingPid = realCallingPid;rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,null /*profilerInfo*/);if (DEBUG_PERMISSIONS_REVIEW) {final ActivityStack focusedStack =mRootActivityContainer.getTopDisplayFocusedStack();Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,true, false) + "} from uid " + callingUid + " on display "+ (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));}}}if (rInfo != null && rInfo.auxiliaryInfo != null) {intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,callingPackage, verificationBundle, resolvedType, userId);resolvedType = null;callingUid = realCallingUid;callingPid = realCallingPid;aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);}//生成一个变量r,记录当前的各项判断结果,然后进一步调用startActivityUnchecked()ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,mSupervisor, checkedOptions, sourceRecord);if (outActivity != null) {outActivity[0] = r;}if (r.appTimeTracker == null && sourceRecord != null) {// If the caller didn't specify an explicit time tracker, we want to continue// tracking under any it has.r.appTimeTracker = sourceRecord.appTimeTracker;}final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();// If we are starting an activity that is not from the same uid as the currently resumed// one, check whether app switches are allowed.if (voiceSession == null && (stack.getResumedActivity() == null|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,realCallingPid, realCallingUid, "Activity start")) {if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {mController.addPendingActivityLaunch(new PendingActivityLaunch(r,sourceRecord, startFlags, stack, callerApp));}ActivityOptions.abort(checkedOptions);return ActivityManager.START_SWITCHES_CANCELED;}}mService.onStartActivitySetDidAppSwitch();mController.doPendingActivityLaunches(false);final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);return res;}
 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {int result = START_CANCELED;final ActivityStack startedActivityStack;try {mService.mWindowManager.deferSurfaceLayout();result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);} finally {..................................................}mService.mWindowManager.continueSurfaceLayout();}postStartActivityProcessing(r, result, startedActivityStack);return result;}

startActivityUnchecked()

//处理并不是用户主观意愿启动的Activity,如来电、闹钟
//判断被启动的对象和调用者是否同一个
//切换动画FLAG_ACTIVITY_NO_ANIMATION
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);

//判断是否要启动新的Task
computeLaunchingTaskFlags()

mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);

ActivityStack.java

void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,boolean newTask, boolean keepCurTransition, ActivityOptions options) {TaskRecord rTask = r.getTaskRecord();final int taskId = rTask.taskId;if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {//将Activity放在stack的最顶层insertTaskAtTop(rTask, r);}TaskRecord task = null;//找到对应的老taskif (!newTask) {// If starting in an existing task, find where that is...boolean startIt = true;for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {task = mTaskHistory.get(taskNdx);if (task.getTopActivity() == null) {// All activities in task are finishing.continue;}if (task == rTask) {// Here it is!  Now, if this is not yet visible to the// user, then just add it without starting; it will// get started when the user navigates back to it.if (!startIt) {if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "+ task, new RuntimeException("here").fillInStackTrace());r.createAppWindowToken();ActivityOptions.abort(options);return;}break;} else if (task.numFullscreen > 0) {startIt = false;}}}// Place a new activity at top of stack, so it is next to interact with the user.// If we are not placing the new activity frontmost, we do not want to deliver the// onUserLeaving callback to the actual frontmost activityfinal TaskRecord activityTask = r.getTaskRecord();if (task == activityTask && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {mStackSupervisor.mUserLeaving = false;}task = activityTask;// Slot the activity into the history stack and proceed//创建appToken,后面你是出来需要给WMSif (r.mAppWindowToken == null) {r.createAppWindowToken();}task.setFrontOfTask();if (!isHomeOrRecentsStack() || numActivities() > 0) {final DisplayContent dc = getDisplay().mDisplayContent;if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,"Prepare open transition: starting " + r);//切换动画if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {dc.prepareAppTransition(TRANSIT_NONE, keepCurTransition);//列表中的Activity不考虑状态迁移动画asaamStackSupervisor.mNoAnimActivities.add(r);} else {int transit = TRANSIT_ACTIVITY_OPEN;if (newTask) {if (r.mLaunchTaskBehind) {transit = TRANSIT_TASK_OPEN_BEHIND;} else {// If a new task is being launched, then mark the existing top activity as// supporting picture-in-picture while pausing only if the starting activity// would not be considered an overlay on top of the current activity// (eg. not fullscreen, or the assistant)if (canEnterPipOnTaskSwitch(focusedTopActivity,null /* toFrontTask */, r, options)) {focusedTopActivity.supportsEnterPipOnTaskSwitch = true;}transit = TRANSIT_TASK_OPEN;}}dc.prepareAppTransition(transit, keepCurTransition);mStackSupervisor.mNoAnimActivities.remove(r);}boolean doShow = true;if (newTask) {// Even though this activity is starting fresh, we still need// to reset it to make sure we apply affinities to move any// existing activities from other tasks in to it.// If the caller has requested that the target task be// reset, then do so.if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {resetTaskIfNeededLocked(r, r);doShow = topRunningNonDelayedActivityLocked(null) == r;}} else if (options != null && options.getAnimationType()== ActivityOptions.ANIM_SCENE_TRANSITION) {doShow = false;}if (r.mLaunchTaskBehind) {// Don't do a starting window for mLaunchTaskBehind. More importantly make sure we// tell WindowManager that r is visible even though it is at the back of the stack.r.setVisibility(true);ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);} else if (SHOW_APP_STARTING_PREVIEW && doShow) {// Figure out if we are transitioning from another activity that is// "has the same starting icon" as the next one.  This allows the// window manager to keep the previous window it had previously// created, if it still had one.TaskRecord prevTask = r.getTaskRecord();ActivityRecord prev = prevTask.topRunningActivityWithStartingWindowLocked();if (prev != null) {// We don't want to reuse the previous starting preview if:// (1) The current activity is in a different task.if (prev.getTaskRecord() != prevTask) {prev = null;}// (2) The current activity is already displayed.else if (prev.nowVisible) {prev = null;}}//将appToken添加到WMSr.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));}} else {// If this is the first activity, don't do any fancy animations,// because there is nothing for it to animate on top of.ActivityOptions.abort(options);}

startActivityLocked()执行完成后,暂停之前的Activity

if (mDoResume) {final ActivityRecord topTaskActivity =mStartActivity.getTaskRecord().topRunningActivityLocked();if (!mTargetStack.isFocusable()|| (topTaskActivity != null && topTaskActivity.mTaskOverlay&& mStartActivity != topTaskActivity)) {mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);mTargetStack.getDisplay().mDisplayContent.executeAppTransition();} else {if (mTargetStack.isFocusable()&& !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {mTargetStack.moveToFront("startActivityUnchecked");}mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);}} else if (mStartActivity != null) {mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());}

RootActivityContainer.java

  boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
//...........................................if (!resumedOnDisplay) {final ActivityStack focusedStack = display.getFocusedStack();if (focusedStack != null) {//恢复当前focus的stack的顶端活动对象focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);}}}return result;}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {if (mInResumeTopActivity) {// Don't even start recursing.return false;}boolean result = false;try {// Protect against recursion.mInResumeTopActivity = true;result = resumeTopActivityInnerLocked(prev, options);final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);if (next == null || !next.canTurnScreenOn()) {checkReadyForSleep();}} finally {mInResumeTopActivity = false;}return result;}

startSpecificActivityLocked() 启动能承载目标Activity的进程

//启动新进程try {if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"+ r.processName);}// Post message to start process to avoid possible deadlock of calling into AMS with the// ATMS lock held.final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());mService.mH.sendMessage(msg);} finally {Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}

启动完成后attachApplication
启动Activity

RootActivityContainer.java

 boolean attachApplication(WindowProcessController app) throws RemoteException {//.............................//启动Activityif (mStackSupervisor.realStartActivityLocked(activity, app,top == activity /* andResume */, true /* checkConfig */)) {didSomething = true;}
//......................
}

后面则是Activity的常规生命周期onCreate()->onStart()->onResume()

流程概括:
1、寻找对应的Activity信息
2、暂停之前的Activity
3、找到或创建进程
4、attchApplication
5、启动Activity

感想:
还有很多疑惑,待后续源码解惑

参考资料:
《深入理解 Android内核设计思想》第八章
https://blog.csdn.net/yun_hen/article/details/78590991

Android startActivity流程相关推荐

  1. 从Zygote孵化frameworks进程,分析StartActivity流程中intent传递数据的最大值。

    Pangu-Immortal (Pangu-Immortal) · GitHub 当我们用Intent传输大数据时,有可能会出现错误: val intent = Intent(this@MainAct ...

  2. startActivity流程(上)

    ActivityManagerService的启动流程 介绍 总体流程 涉及的数据结构 ProcessRecord(进程) ActivityRecord TaskRecord ActivityStac ...

  3. android SystemUI 流程分析

    android4 SystemUI 流程分析 什么是SystemUI? 对于Phone来说SystemUI指的是:StatusBar(状态栏).NavigationBar(导航栏).而对于Tablet ...

  4. 8.学习Camera之——Android开机流程

    Android系统启动流程 要求:掌握Android系统的启动流程,每个阶段的区别和作用. 一. android系统架构 andorid系统架构从上到下分别有应用层.应用框架层.系统运行时库层.硬件抽 ...

  5. Android绘制流程

    一.前言 1.1.C++界面库 MFC.WTL.DuiLib.QT.Skia.OpenGL. Android里面的画图分为2D和3D两种: 2D是由Skia 来实现的,3D部分是由OpenGL实现的. ...

  6. Android事件流程详解

    Android事件流程详解 网络上有不少博客讲述了android的事件分发机制和处理流程机制,但是看过千遍,总还是觉得有些迷迷糊糊,因此特地抽出一天事件来亲测下,向像我一样的广大入门程序员详细讲述an ...

  7. Android系统启动流程分析之安装应用

    2016六月 21 原 Android系统启动流程分析之安装应用 分类:Android系统源码研究 (295)  (0)  举报  收藏 跟随上一篇博客Android系统的启动流程简要分析继续分析an ...

  8. Android构建流程——篇二

    文章目录 预操作 任务列表 如何查看一个task类 Task1: checkDebugClasspath 1. input/output 2. 如何找到任务实现类 3. 核心类(AppClasspat ...

  9. Android构建流程——篇一

    Android构建流程 前言 APK 构建流程 AGP(3.2.0)任务列表总览图 参考文献 前言 大家平时开发Android项目时一般都是点击AS run按钮,这样apk会自动安装到手机上,这整个过 ...

最新文章

  1. C++ Windows进程管理
  2. 正向代理和反向代理??
  3. 2019求职面经推荐(算法工程师-来自知乎某位大佬)
  4. redis api java 正则_java代码怎么正则删除redis的数据
  5. python空间分析_读书笔记——《python地理空间分析指南》
  6. mysql 备份文件太大_mysql数据库太大了怎么备份
  7. OpenCASCADE:使用 XSTEPDRAW
  8. WCF系列(五) -- 也谈序列化(下)
  9. [BUUCTF-pwn]——jarvisoj_level1
  10. spray.json.JsonParser$ParsingException: Unexpected end-of-input at input index
  11. P3273-[SCOI2011]棘手的操作【线段树,并查集】
  12. HTML5炫彩舞蹈学院官网网站模板
  13. 实现原理 扫描枪_条码扫描枪工作原理
  14. java找_Java基础之:查找
  15. Php.ini文件位置在哪里 Php.ini文件找不到
  16. 基于c语言的成绩管理系统,基于C语言实现学生成绩管理系统.docx
  17. tomcat日志按天分割
  18. Idea2017 破解版下载注册步骤(含注册码),亲测可用
  19. 学计算机选择师范类好吗,师范教育类专业和计算机类专业,两者相比,哪个更适合自考生报读...
  20. bzoj1861 [Zjoi2006]Book 书架

热门文章

  1. 引擎十一:体积感SSS,SSR
  2. c语言fclose函数作用,如若没有正确使用fclose函数,会怎样
  3. XSS漏洞分类及危害
  4. stm32f407关于独立看门狗各种函数(一)(HAL库)
  5. js 使用setInterval()实现实时刷新
  6. 小白的笨笨知识【用原生js实现一个倒计时项目】
  7. spring+maven+log4j2 配置
  8. Django——Cookie
  9. MSN病毒性感相册一个变种的手工杀毒方法
  10. MyBatis-Plus 从入门到精通,这一篇就够了【推荐收藏】