Activity 启动流程分析(二)一天搞懂所有疑难杂问

195 阅读17分钟

前言

本文将结合源码,详细分析Activity的启动流程。希望帮助大家理解与掌握。同时若文中存在错误,或有不易理解的地方,也请大家帮忙指正,一起学习,共同涨薪。

上接:Activity 启动流程分析(一)一天搞懂所有疑难杂问

image.png

一、准备启动目标Activity


ActivityStack.resumeTopActivityInnerLocked(下半部分,发送Resume请求)

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n5" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
 @GuardedBy("mService")
 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
 // .....
 //以上省略,主要是PasueActivity窗口隐藏,过渡动画等部分
 ActivityStack lastStack = mStackSupervisor.getLastStack();
 //通过缓存的ProcressRecord中的IApplicationThread来判断进程是否存在
 if (next.app != null && next.app.thread != null) {
 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
 + " stopped=" + next.stopped + " visible=" + next.visible);

 // 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 = lastStack != null
 && (lastStack.inMultiWindowMode()
 || (lastStack.mLastPausedActivity != null
 && !lastStack.mLastPausedActivity.fullscreen));

 // The contained logic must be synchronized, since we are both changing the visibility
 // and updating the {@link Configuration}. {@link ActivityRecord#setVisibility} will
 // ultimately cause the client code to schedule a layout. Since layouts retrieve the
 // current {@link Configuration}, we must ensure that the below code updates it before
 // the layout can occur.
 synchronized(mWindowManager.getWindowManagerLock()) {
 // This activity is now becoming visible.
 if (!next.visible || next.stopped || lastActivityTranslucent) {
 next.setVisibility(true);
 }

 // schedule launch ticks to collect information about slow apps.
 next.startLaunchTickingLocked();

 ActivityRecord lastResumedActivity =
 lastStack == null ? null :lastStack.mResumedActivity;
 final ActivityState lastState = next.getState();

 mService.updateCpuStats();

 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
 + " (in existing)");

 next.setState(RESUMED, "resumeTopActivityInnerLocked");

 mService.updateLruProcessLocked(next.app, true, null);
 updateLRUListLocked(next);
 mService.updateOomAdjLocked();

 // Have the window manager re-evaluate the orientation of
 // the screen based on the new activity order.
 boolean notUpdated = true;

 if (mStackSupervisor.isFocusedStack(this)) {
 // 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.
 notUpdated = !mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
 true /* markFrozenIfConfigChanged */, false /* deferResume */);
 }

 if (notUpdated) {
 // The configuration update wasn't able to keep the existing
 // instance of the activity, and instead started a new one.
 // We should be all done, but let's just make sure our activity
 // is still at the top and schedule another run if something
 // weird happened.
 ActivityRecord nextNext = topRunningActivityLocked();
 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
 "Activity config changed during resume: " + next
 + ", new next: " + nextNext);
 if (nextNext != next) {
 // Do over!
 mStackSupervisor.scheduleResumeTopActivities();
 }
 if (!next.visible || next.stopped) {
 next.setVisibility(true);
 }
 next.completeResumeLocked();
 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
 return true;
 }

 try {
 final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
 next.appToken);
 // Deliver all pending results.
 ArrayList<ResultInfo> a = next.results;
 if (a != null) {
 final int N = a.size();
 if (!next.finishing && N > 0) {
 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
 "Delivering results to " + next + ": " + a);
 transaction.addCallback(ActivityResultItem.obtain(a));
 }
 }

 if (next.newIntents != null) {
 transaction.addCallback(NewIntentItem.obtain(next.newIntents,
 false /* andPause */));
 }

 // Well the app will no longer be stopped.
 // Clear app token stopped state in window manager if needed.
 next.notifyAppResumed(next.stopped);

 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
 System.identityHashCode(next), next.getTask().taskId,
 next.shortComponentName);

 next.sleeping = false;
 mService.getAppWarningsLocked().onResumeActivity(next);
 mService.showAskCompatModeDialogLocked(next);
 next.app.pendingUiClean = true;
 next.app.forceProcessStateUpTo(mService.mTopProcessState);
 next.clearOptionsLocked();
 //设置ResumeActivityItem生命周期的执行
 transaction.setLifecycleStateRequest(
 ResumeActivityItem.obtain(next.app.repProcState,
 mService.isNextTransitionForward()));
 调度到App进程
 mService.getLifecycleManager().scheduleTransaction(transaction);

 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
 + next);
 } catch (Exception e) {
 // Whoops, need to restart this activity!
 if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
 + lastState + ": " + next);
 next.setState(lastState, "resumeTopActivityInnerLocked");

 // lastResumedActivity being non-null implies there is a lastStack present.
 if (lastResumedActivity != null) {
 lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
 }

 Slog.i(TAG, "Restarting because process died: " + next);
 if (!next.hasBeenLaunched) {
 next.hasBeenLaunched = true;
 } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null
 && lastStack.isTopStackOnDisplay()) {
 next.showStartingWindow(null /* prev */, false /* newTask */,
 false /* taskSwitch */);
 }
 mStackSupervisor.startSpecificActivityLocked(next, true, false);
 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
 return true;
 }
 }

 // From this point on, if something goes wrong there is no way
 // to recover the activity.
 try {
 //进行resume的后续工作
 next.completeResumeLocked();
 } catch (Exception e) {
 // If any exception gets thrown, toss away this
 // activity and try the next one.
 Slog.w(TAG, "Exception thrown during resume of " + next, e);
 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
 "resume-exception", true);
 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
 return true;
 }
 } else {
 // Whoops, need to restart this activity!
 if (!next.hasBeenLaunched) {
 next.hasBeenLaunched = true;
 } else {
 if (SHOW_APP_STARTING_PREVIEW) {
 next.showStartingWindow(null /* prev */, false /* newTask */,
 false /* taskSwich */);
 }
 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
 }
 //进程不存在或无效,执行startSpecificActivityLocked
 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
 mStackSupervisor.startSpecificActivityLocked(next, true, true);
 }

 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
 return true;
 } </pre>

从上面可以看出,这一部分主要是,判断该进程是否存在,存在则直接发送ResumeActivityItem请求,通知APP执行Resume操作,不存在则调用 startSpecificActivityLocked,下面已进程不存在的情况,继续跟踪

二、启动新的APP进程

ActivityStackSupervisor.startSpecificActivityLocked

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n10" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
 void startSpecificActivityLocked(ActivityRecord r,
 boolean andResume, boolean checkConfig) {
 // Is this activity's application already running?
 //获取目标Activity的进程信息
 ProcessRecord app = mService.getProcessRecordLocked(r.processName,
 r.info.applicationInfo.uid, true);

 getLaunchTimeTracker().setLaunchTime(r);
 //判断目标进程是否存在
 if (app != null && app.thread != null) {
 try {
 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
 || !"android".equals(r.info.packageName)) {
 // Don't add this if it is a platform component that is marked
 // to run in multiple processes, because this is actually
 // part of the framework so doesn't make sense to track as a
 // separate apk in the process.
 app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
 mService.mProcessStats);
 }
 realStartActivityLocked(r, app, andResume, checkConfig);
 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.
 }

 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
 "activity", r.intent.getComponent(), false, false, true);
 } </pre>

上面方法里面通过getProcessRecordLocked获取目标App的进程,并判断进程是否存在或有效,来确认下一步流程,若进程存在 则调用realStartActivityLocked继续启动流程,若不存在则调用startProcessLocked,启动目标进程

ActivityManagerService.startProcessLocked

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n13" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
 long startTime = SystemClock.elapsedRealtime();
 ProcessRecord app;
 //...省略
 if (app == null) {
 checkTime(startTime, "startProcess: creating new process record");
 //创建ProcessRecord实例,并存入AMS.mProgressNames中保存
 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
 if (app == null) {
 Slog.w(TAG, "Failed making new process record for "
 + processName + "/" + info.uid + " isolated=" + isolated);
 return null;
 }
 app.crashHandler = crashHandler;
 app.isolatedEntryPoint = entryPoint;
 app.isolatedEntryPointArgs = entryPointArgs;
 checkTime(startTime, "startProcess: done creating new process record");
 } else {
 // If this is a new package in the process, add the package to the list
 app.addPackage(info.packageName, info.versionCode, mProcessStats);
 checkTime(startTime, "startProcess: added package to existing proc");
 }

 // If the system is not ready yet, then hold off on starting this
 // process until it is.
 //系统未就绪的处理
 if (!mProcessesReady
 && !isAllowedWhileBooting(info)
 && !allowWhileBooting) {
 if (!mProcessesOnHold.contains(app)) {
 mProcessesOnHold.add(app);
 }
 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
 "System not ready, putting on hold: " + app);
 checkTime(startTime, "startProcess: returning with proc on hold");
 return app;
 }

 checkTime(startTime, "startProcess: stepping in to startProcess");
 //进一步执行启动进程
 final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
 checkTime(startTime, "startProcess: done starting proc!");
 return success ? app : null;
 } </pre>

这儿又会继续调用startProcessLocked的重载方法,最后会调用到startProcess方法里面

ActivityManagerService.startProcess

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n16" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
 private ProcessStartResult startProcess(String hostingType, String entryPoint,
 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
 long startTime) {
 try {
 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
 app.processName);
 checkTime(startTime, "startProcess: asking zygote to start proc");
 final ProcessStartResult startResult;
 //判断是否为webview_service
 if (hostingType.equals("webview_service")) {
 startResult = startWebView(entryPoint,
 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
 app.info.dataDir, null,
 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
 } else {
 startResult = Process.start(entryPoint,
 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
 app.info.dataDir, invokeWith,
 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
 }
 checkTime(startTime, "startProcess: returned from zygote!");
 return startResult;
 } finally {
 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 }
 } </pre>

判断是否为webview_service,否则调用Process.start启动进程,找到Process.start

Process.start

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n19" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/os/Process.java
 public static final ProcessStartResult start(final String processClass,
 final String niceName,
 int uid, int gid, int[] gids,
 int runtimeFlags, int mountExternal,
 int targetSdkVersion,
 String seInfo,
 String abi,
 String instructionSet,
 String appDataDir,
 String invokeWith,
 String[] zygoteArgs) {
 return zygoteProcess.start(processClass, niceName, uid, gid, gids,
 runtimeFlags, mountExternal, targetSdkVersion, seInfo,
 abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
 } </pre>

只是间接调用的zygoteProcess.start方法,继续向下

ZygoteProcess.start

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n22" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/os/ZygoteProcess.java
 public final Process.ProcessStartResult start(final String processClass,
 final String niceName,
 int uid, int gid, int[] gids,
 int runtimeFlags, int mountExternal,
 int targetSdkVersion,
 String seInfo,
 String abi,
 String instructionSet,
 String appDataDir,
 String invokeWith,
 String[] zygoteArgs) {
 try {
 return startViaZygote(processClass, niceName, uid, gid, gids,
 runtimeFlags, mountExternal, targetSdkVersion, seInfo,
 abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
 zygoteArgs);
 } catch (ZygoteStartFailedEx ex) {
 Log.e(LOG_TAG,
 "Starting VM process through Zygote failed");
 throw new RuntimeException(
 "Starting VM process through Zygote failed", ex);
 }
 } </pre>

调用了startViaZygote

ZygoteProcess.startViaZygote

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n25" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/os/ZygoteProcess.java
 private Process.ProcessStartResult startViaZygote(final String processClass,
 final String niceName,
 final int uid, final int gid,
 final int[] gids,
 int runtimeFlags, int mountExternal,
 int targetSdkVersion,
 String seInfo,
 String abi,
 String instructionSet,
 String appDataDir,
 String invokeWith,
 boolean startChildZygote,
 String[] extraArgs)
 throws ZygoteStartFailedEx {
 ArrayList<String> argsForZygote = new ArrayList<String>();

 // --runtime-args, --setuid=, --setgid=,
 // and --setgroups= must go first
 argsForZygote.add("--runtime-args");
 argsForZygote.add("--setuid=" + uid);
 argsForZygote.add("--setgid=" + gid);
 argsForZygote.add("--runtime-flags=" + runtimeFlags);
 if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
 argsForZygote.add("--mount-external-default");
 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
 argsForZygote.add("--mount-external-read");
 } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
 argsForZygote.add("--mount-external-write");
 }
 argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

 //...省略这部分代码,主要是设置启动参数
 if (extraArgs != null) {
 for (String arg : extraArgs) {
 argsForZygote.add(arg);
 }
 }

 synchronized(mLock) {
 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
 }
 } </pre>

可以看出这个函数,会计算启动应用进程的各个参数,然后再调用zygoteSendArgsAndGetResult方法

ZygoteProcess.startViaZygote

**

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n28" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/os/ZygoteProcess.java
 private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
 ZygoteState zygoteState, ArrayList<String> args)
 throws ZygoteStartFailedEx {
 try {
 // Throw early if any of the arguments are malformed. This means we can
 // avoid writing a partial response to the zygote.
 int sz = args.size();
 for (int i = 0; i < sz; i++) {
 if (args.get(i).indexOf('\n') >= 0) {
 throw new ZygoteStartFailedEx("embedded newlines not allowed");
 }
 }

 /**
 * See com.android.internal.os.SystemZygoteInit.readArgumentList()
 * Presently the wire format to the zygote process is:
 * a) a count of arguments (argc, in essence)
 * b) a number of newline-separated argument strings equal to count
 *
 * After the zygote process reads these it will write the pid of
 * the child or -1 on failure, followed by boolean to
 * indicate whether a wrapper process was used.
 */
 final BufferedWriter writer = zygoteState.writer;
 final DataInputStream inputStream = zygoteState.inputStream;

 writer.write(Integer.toString(args.size()));
 writer.newLine();

 for (int i = 0; i < sz; i++) {
 String arg = args.get(i);
 writer.write(arg);
 writer.newLine();
 }

 writer.flush();

 // Should there be a timeout on this?
 Process.ProcessStartResult result = new Process.ProcessStartResult();

 // Always read the entire result from the input stream to avoid leaving
 // bytes in the stream for future process starts to accidentally stumble
 // upon.
 result.pid = inputStream.readInt();
 result.usingWrapper = inputStream.readBoolean();

 if (result.pid < 0) {
 throw new ZygoteStartFailedEx("fork() failed");
 }
 return result;
 } catch (IOException ex) {
 zygoteState.close();
 throw new ZygoteStartFailedEx(ex);
 }
 } </pre>

这个函数将这些参数通过socket发送给zygote进程,zygote进程会孵化出新的dalvik应用进程,然后告诉ActivityManagerService新启动的进程的pid 至于zygote具体的孵化过程就不再详细看下去了,不然跑远了,这部分后续会在Android启动流程中再深入研究 当APP进程创建后会调用AMS的attachApplication方法通知进程启动完成

三、进程启动完成

ActivityManagerService.attachApplicationLocked

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n33" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {

        // Find the application record that is being attached...  either via
        // the pid if we are running in multiple processes, or just pull the
        // next app record if we are emulating process with anonymous threads.
        ProcessRecord app;
        long startTime = SystemClock.uptimeMillis();
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }

        //省略
        //标志进程已经准备好启动
        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);

        //省略

        // Remove this record from the list of starting applications.
        mPersistentStartingProcesses.remove(app);
        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
                "Attach application locked removing on hold: " + app);
        mProcessesOnHold.remove(app);

        boolean badApp = false;
        boolean didSomething = false;

        // See if the top visible activity is waiting to run in this process...
        //查看有没有活动正在等待此进程的启动
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        //省略

        return true;
    } </pre>

这里会继续调用mStackSupervisor.attachApplicationLocked

ActivityStackSupervisor.attachApplicationLocked

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n36" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        //标记是否有启动组件
        boolean didSomething = false;
        //遍历ActivityDisplay(一个ActivityDisplay对应一个显示屏幕)
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = display.getChildAt(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                            //启动等待resume的Activity
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                    + top.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    } </pre>

可以看出AMS在收到APP进程启动完成后,会调用realStartActivityLocked启动因为等待目标进程启动而暂缓的Activity

四、准备启动目标Activity

ActivityStackSupervisor.realStartActivityLocked

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n41" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

        if (!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.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }

        final TaskRecord task = r.getTask();
        final ActivityStack stack = task.getStack();

        beginDeferResume();

        try {
            //省略

            try {
                if (app.thread == null) {
                    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;
                }
                //省略

                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                //创建LaunchActivityItem并添加到mActivityCallbacks里保存
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                //此时为teue,设置ResumeActivityItem为Activity最终期望的状态
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                //设置给LifecycleStateRequest
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                //调用给App进程
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                //省略

            } 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);
                    mService.appDiedLocked(app);
                    stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "2nd-crash", false);
                    return false;
                }

                // This is the first time we failed -- restart process and
                // retry.
                r.launchFailed = true;
                app.activities.remove(r);
                throw e;
            }
        } finally {
            endDeferResume();
        }

        //省略
        return true;
    } </pre>

方法中创建ClientTransaction对象,添加LaunchActivityItem和ResumeActivityItem两个子项,并发送给APP进程执行相应处理。 发送过程在Pause中已经跟了一遍了,不继续重复 最后这里会先处理LaunchActivityItem,调用它的execute方法,execute中会创建ActivityClientRecord对象,然后调用ActivityThread的handleLaunchActivity方法并传入ActivityClientRecord

五、onCreate处理

ActivityThread.handleLaunchActivity

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n46" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/app/ActivityThread.java
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        //移除GC空闲消息
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);

        // Initialize before creating the activity
        if (!ThreadedRenderer.sRendererDisabled) {
            GraphicsEnvironment.earlyInitEGL();
        }
        WindowManagerGlobal.initialize();

        //执行启动Activity并返回Activity实例
        final Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            if (!r.activity.mFinished && pendingActions != null) {
                pendingActions.setOldState(r.state);
                pendingActions.setRestoreInstanceState(true);
                pendingActions.setCallOnPostCreate(true);
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        return a;
    } </pre>

看下performLaunchActivity的实现

ActivityThread.performLaunchActivity

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n49" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/app/ActivityThread.java
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        //获取LoadedApk对象
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
        //获取ComponentName
        ComponentName component = r.intent.getComponent();
        if (component == null) {
            //intent中未显示设置,从PackageManagerService中查找匹配的resolveInfo构建的ComponentName
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            //若Activity设置了别名(targetActivity属性),则使用targetActivity构建ComponentName
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        //获取ContextImpl实例
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //通过反射实例化Activity
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            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 {
            //获取LoadedApk中缓存的Application对象(在App进程启动时实例化)
            Application app = r.packageInfo.makeApplication(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());

            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                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赋值给ContextImpl的mOuterContex,使其持有Activity的引用
                appContext.setOuterContext(activity);
                //进行Activity的成员赋值和初始化等操作
                activity.attach(appContext, 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.configCallback);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    //设置主题
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    //设置了Persistable模式,将触发两个参数的onCreate生命周期回调
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    //触发一个参数的onCreate回调
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
            }
            //更新ActivityClientRecord中的状态
            r.setState(ON_CREATE);
            //保存ActivityClientRecord
            mActivities.put(r.token, r);

        } 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;
    } </pre>

总结一下该方法 1.获取ComponentName 2.实例化ContextImpl 3.通过反射实例化目标Activity 4.触发onCreate生命周期回调,ActivityClientRecord中mLifecycleState成员(生命周期状态)被设置为ON_CREATE 当LaunchActivityItem处理完后,便轮到了ResumeActivityItem,在TransactionExecutor的executeLifecycleState方法 这个方法在上面Pause的过程中,已经看过了,没印象的可以回头看一下,此时Activity状态为ON_CREATE,但是ResumeActivityItem中保存的期望状态是ON_RESUME, 在cycleToPath方法中会先调用handleStartActivity方法,进行Activity start阶段的处理

六、onStart处理

ActivityThread.handleStartActivity

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n54" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/app/ActivityThread.java
    @Override
    public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        final Activity activity = r.activity;
        if (r.activity == null) {
            // TODO(lifecycler): What do we do in this case?
            return;
        }
        if (!r.stopped) {
            throw new IllegalStateException("Can't start activity that is not stopped.");
        }
        if (r.activity.mFinished) {
            // TODO(lifecycler): How can this happen?
            return;
        }

        // Start
        //performStart里通过Instrumentation调用Activity的onStart生命周期回调方法
        activity.performStart("handleStartActivity");
        //设置生命周期状态为ON_START
        r.setState(ON_START);

        if (pendingActions == null) {
            // No more work to do.
            return;
        }

        // Restore instance state
        if (pendingActions.shouldRestoreInstanceState()) {
            if (r.isPersistable()) {
                if (r.state != null || r.persistentState != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                            r.persistentState);
                }
            } else if (r.state != null) {
                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
            }
        }

        // Call postOnCreate()
        if (pendingActions.shouldCallOnPostCreate()) {
            activity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnPostCreate(activity, r.state,
                        r.persistentState);
            } else {
                mInstrumentation.callActivityOnPostCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString()
                                + " did not call through to super.onPostCreate()");
            }
        }
    } </pre>

上面方法,调用了onStart生命周期方法,并且将Activity的生命周期状态设置为ON_START 接下来将继续执行handleResumeActivity

七、onResume处理

ActivityThread.handleResumeActivity

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n59" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/app/ActivityThread.java
    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        // TODO Push resumeArgs into the activity for consideration
        //该方法中看情况调用onRestart生命周期回调方法,接着调用onResume生命周期方法
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        if (r == null) {
            // We didn't actually resume the activity, so skipping any follow-up actions.
            return;
        }
        //以下省略
        //主要是DecorView、ViewRootImpl、WindowManager相关初始化操作,向WindowManagerService注册窗口,设置视图树可见

        r.nextIdle = mNewActivities;
        mNewActivities = r;
        if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
        //向当前线程添加一个闲时消息
        Looper.myQueue().addIdleHandler(new Idler());
    } </pre>

该方法主要时调用onResume生命周期方法,设置状态为ON_RESUME,如果当前Activity是首次启动, 则还需要进行DecorView、ViewRootImpl、WindowManager相关初始化操作,向WindowManagerService注册窗口,设置视图树可见。 由此可以得知,Activity首次启动的时候是在onResume后才真正可见,并不是onStart时就部分可见

该方法最后,往当前线程Looper中的消息队列中添加一个闲时消息Idler,当消息队列中无消息处理时将回调它的queueIdle方法, 在queueIdle中又会通过IActivityManager调用AMS的activityIdle方法

八、onStop处理

APP进程通过activityIdle方法通知AMS目标Activity的resume操作完成,其中会根据token取得对应的ActivityStack,调用它的activityIdleInternalLocked方法

ActivityStackSupervisor.activityIdleInternalLocked

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n66" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            boolean processPausingActivities, Configuration config) {
        if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);

        ArrayList<ActivityRecord> finishes = null;
        ArrayList<UserState> startingUsers = null;
        int NS = 0;
        int NF = 0;
        boolean booting = false;
        boolean activityRemoved = false;

        ActivityRecord r = ActivityRecord.forTokenLocked(token);
        //省略

        //获取paused的ActivityRecord集合,ActivityPaused后会加入mStopngActivityies保存
        // Atomically retrieve all of the other things to do.
        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
                true /* remove */, processPausingActivities);
        NS = stops != null ? stops.size() : 0;
        if ((NF = mFinishingActivities.size()) > 0) {
            finishes = new ArrayList<>(mFinishingActivities);
            //mFinishingActivities保存的已经stop等待finish的ActivityRecord集合
            mFinishingActivities.clear();
        }

        if (mStartingUsers.size() > 0) {
            startingUsers = new ArrayList<>(mStartingUsers);
            mStartingUsers.clear();
        }

        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NS; i++) {
            //依次取出ActivityRecord,对其执行stop或finish操作
            r = stops.get(i);
            final ActivityStack stack = r.getStack();
            if (stack != null) {
                if (r.finishing) {
                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
                            "activityIdleInternalLocked");
                } else {
                    stack.stopActivityLocked(r);
                }
            }
        }

        //省略

        return r;
    } </pre>

这里面主要是获取之前保存的等待stop或则finish的ActivityRecord,执行对应的操作,来看一下stopActivityLocked

ActivityStack.stopActivityLocked

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n69" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> ///frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
    final void stopActivityLocked(ActivityRecord r) {
        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
            if (!r.finishing) {
                if (!shouldSleepActivities()) {
                    if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
                    if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "stop-no-history", false)) {
                        // If {@link requestFinishActivityLocked} returns {@code true},
                        // {@link adjustFocusedActivityStack} would have been already called.
                        r.resumeKeyDispatchingLocked();
                        return;
                    }
                } else {
                    if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
                            + " on stop because we're just sleeping");
                }
            }
        }

        if (r.app != null && r.app.thread != null) {
            adjustFocusedActivityStack(r, "stopActivity");
            r.resumeKeyDispatchingLocked();
            try {
                r.stopped = false;
                if (DEBUG_STATES) Slog.v(TAG_STATES,
                        "Moving to STOPPING: " + r + " (stop requested)");
                r.setState(STOPPING, "stopActivityLocked");
                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                        "Stopping visible=" + r.visible + " for " + r);
                if (!r.visible) {
                    r.setVisible(false);
                }
                EventLogTags.writeAmStopActivity(
                        r.userId, System.identityHashCode(r), r.shortComponentName);
                //通过StopActivityItem封装的事务,调度到App进程
                mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
                        StopActivityItem.obtain(r.visible, r.configChangeFlags));
                if (shouldSleepOrShutDownActivities()) {
                    r.setSleeping(true);
                }
                //发送超时消息
                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
                mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
            } catch (Exception e) {
                // Maybe just ignore exceptions here...  if the process
                // has crashed, our death notification will clean things
                // up.
                Slog.w(TAG, "Exception thrown during pause", e);
                // Just in case, assume it to be stopped.
                r.stopped = true;
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
                r.setState(STOPPED, "stopActivityLocked");
                if (r.deferRelaunchUntilPaused) {
                    destroyActivityLocked(r, true, "stop-except");
                }
            }
        }
    } </pre>

这里很熟悉,和前面的Pause,和resume流程差不多stopActivityLocked方法中发送ClientTransaction到对应APP进程(之前pause的Activity所在进程),然后调用StopActivityItem的execute方法, 其中将调用ActivityThread的handleStopActivity方法

ActivityThread.handleStopActivity

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n72" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/app/ActivityThread.java
    @Override
    public void handleStopActivity(IBinder token, boolean show, int configChanges,
            PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
        final ActivityClientRecord r = mActivities.get(token);
        r.activity.mConfigChangeFlags |= configChanges;
        //继承自Runnable,用于保存stop相关参数和通知AMS的结果
        final StopInfo stopInfo = new StopInfo();
        // 将调用onStop生命周期的回调方法,设置状态ON_STOP,视情况调用onSveInstanceState回调方法
        performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
                reason);

        if (localLOGV) Slog.v(
            TAG, "Finishing stop of " + r + ": show=" + show
            + " win=" + r.window);

        updateVisibility(r, show);

        // Make sure any pending writes are now committed.
        if (!r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }

        stopInfo.setActivity(r);
        stopInfo.setState(r.state);
        stopInfo.setPersistentState(r.persistentState);
        //将stopInfo添加到pendingActions保存
        pendingActions.setStopInfo(stopInfo);
        mSomeActivitiesChanged = true;
    } </pre>

该方法创建了StopInfo来保存stop过程相关参数,接着调用performStopActivityInner方法,设置状态为ON_STOP, 并且视情况调用onSveInstanceState回调方法,最后将stopInfo添加进pendingActions保存 StopActivityItem在执行完execute方法后,会执行postExecute方法,而在这个方法中会调用ActivityThread的reportStop方法

ActivityThread.reportStop

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n75" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/app/ActivityThread.java
    @Override
    public void reportStop(PendingTransactionActions pendingActions) {
        mH.post(pendingActions.getStopInfo());
    } </pre>

这里从pendingActions中取出先前保存的StopInfo,切换到主线程执行。StopInfo继承自Runnable,将触发它的run方法

PendingTransactionActions.StopInfo.run

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n78" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/core/java/android/app/servertransaction/PendingTransactionActions.java
    @Override
    public void run() {
        // Tell activity manager we have been stopped.
        try {
            if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + mActivity);
            // TODO(lifecycler): Use interface callback instead of AMS.
            //调用AMS的ActivityStopped方法通知AMS
            ActivityManager.getService().activityStopped(
                    mActivity.token, mState, mPersistentState, mDescription);
        } catch (RemoteException ex) {
            // Dump statistics about bundle to help developers debug
            final LogWriter writer = new LogWriter(Log.WARN, TAG);
            final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
            pw.println("Bundle stats:");
            Bundle.dumpStats(pw, mState);
            pw.println("PersistableBundle stats:");
            Bundle.dumpStats(pw, mPersistentState);

            if (ex instanceof TransactionTooLargeException
                    && mActivity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
                Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
                return;
            }
            throw ex.rethrowFromSystemServer();
        }
    } </pre>

AMS的activityStopped方法中会根据token查找对应的ActivityRecord,再调用其activityStoppedLocked方法

ActivityRecord.activityStoppedLocked

**

<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n81" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> // /frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
    final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
            CharSequence description) {
        final ActivityStack stack = getStack();
        if (mState != STOPPING) {
            Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
            stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
            return;
        }
        if (newPersistentState != null) {
            persistentState = newPersistentState;
            service.notifyTaskPersisterLocked(task, false);
        }
        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);

        if (newIcicle != null) {
            // If icicle is null, this is happening due to a timeout, so we haven't really saved
            // the state.
            icicle = newIcicle;
            haveState = true;
            launchCount = 0;
            updateTaskDescription(description);
        }
        if (!stopped) {
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
            stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
            stopped = true;
            setState(STOPPED, "activityStoppedLocked");

            mWindowContainerController.notifyAppStopped();

            if (finishing) {
                clearOptionsLocked();
            } else {
                if (deferRelaunchUntilPaused) {
                    stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                } else {
                    mStackSupervisor.updatePreviousProcessLocked(this);
                }
            }
        }
    } </pre>

到这里就完成了stop操作,和通知AMS,启动的整个流程也就结束了,当然还有多种情况可以分析的,比如销毁的时候,返回操作的 时候,这里就不一一分析了,主要是了解其流程,理解思路,便于在遇到相关问题时,有更好的处理方法,正所谓知己知彼百战不殆嘛

总结

最后来总结一下整个启动流程

  1. 首先APP发起startActivity请求
  2. 经过一系列调用,到AMS的startActivityAsUser方法
  3. 调用ActivityStartController.obtainStarter,设置所有启动参数,返回一个ActivityStarter对象,同时执行execute方法
  4. 接着调用ActivityStarter的startActivityMayWait方法,解析出与Intent对应的ActivityInfo,并获取到启动该Activity的前台Tas然后通过startActivity启动Activity并对启动结果进行处理
  5. startActivity里面会调用startActivityUnchecked,主要是对Activity启动模式的处理,设置对应的task并带到前台之后,开始启动对应的Activity 通过调用ActivityStack.startActivityLocked为新开启的Activity创建Task,并将Task保存在ActivityRecord 然后调用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked,最终会调用到ActivityStack.resumeTopActivityInnerLocked方法
  6. ActivityStack.resumeTopActivityInnerLocked前半部分通过ActivityStack.startPausingLocked去暂停当前运行的Activity,最终执行ActivityThread.handlePauseActivity
  7. 调用AMS的activityPaused,通知Activity pause完成
  8. AMS最终会调用ActivityStack.completePauseLocked来将这次pause的ActivityRecord存入ActivityStackSupervisor的mStoppingActivities成员(ArrayList)中,用于后续再对其执行stop和finish操作
  9. 当上一个Activity Pause操作结束后,在ActivityStack.resumeTopActivityInnerLocked下半部分,会根据需要确认是否需要创建新的进程
  10. 需要则通过AMS发起ActivityManagerService.startProcessLocked,最终到Zygote孵化进程,fock新的进程,创建成功后调用AMS的attachApplication方法通知进程启动完成
  11. AMS在收到APP进程启动完成后,会调用realStartActivityLocked启动因为等待目标进程启动而暂缓的Activity
  12. 调用ActivityThread.performLaunchActivity,实例化ContextImpl,通过反射实例化目标Activity,触发onCreate生命周期回调,设置生命周期状态为ON_CREATE
  13. 调用ActivityThread.handleStartActivity方法,触发onStart生命周期方法,并且将Activity的生命周期状态设置为ON_START
  14. 调用ActivityThread.handleResumeActivity方法,触发onResume生命周期方法,设置状态为ON_RESUME,如果当前Activity是首次启动,则还需要进行DecorView、ViewRootImpl、WindowManager相关初始化操作,向WindowManagerService注册窗口,设置视图树可见
  15. APP进程通过activityIdle方法通知AMS目标Activity的resume操作完成,最后会调用到ActivityThread.handleStopActivity方法,触发onStop生命周期并设置状态为ON_STOP
  16. 调用AMS的ActivityStopped方法通知AMS
  17. AMS的activityStopped方法中会根据token查找对应的ActivityRecord,再调用其activityStoppedLocked方法

...
因篇幅原因,本章节分为两篇文章进行讲解,上篇更新了Activity启动流程(一)。其他Android开发中高级知识点也在持续更新中~