接着上一篇繼續去追蹤Activity_B生命週期回調源碼。java
繼續分析,在performPauseActivity方法中,回調了Activity的兩個操做函數:
一 個是用於保存狀態的onSaveInstanceState(),另外一個就是onPause() ,這裏你應該瞭解onPause和onSaveInstanceState的調用順序了,這裏看來OnSaveInstanceState是先於onPause的調用的,可是打印的Log顯示onSaveInstanceState在onPause以後,在onStop以前調用(不明白)。android
![](http://static.javashuo.com/static/loading.gif)
最後r.state置爲true。app
當 AmS通知當前Activity暫停後,AmS會當即返回,而在目標進程中則是發送一個暫停的消息,處理完該暫停消息後,目標進程會調用AmS的 activityPaused(),報 告 AMS本身已經暫停完畢,而後執行ActivityManagerNative.getDefault().activityPaused(token)
從而AMS將開始啓動真正的Activity。異步
前面說過,ActivityManagerNative.getDefault().activityPaused的動做執行者是ActivityManagerService.activityPaused
ActivityManagerService.classide
[java] view plain copy函數
- public final void activityPaused(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- synchronized(this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- stack.activityPausedLocked(token, false);
- }
- }
- Binder.restoreCallingIdentity(origId);
- }
ActivityStack.class
[java] view plain copyoop
- final void activityPausedLocked(IBinder token, boolean timeout) {
- if (DEBUG_PAUSE) Slog.v(
- TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
-
- final ActivityRecord r = isInStackLocked(token);
- if (r != null) {
- mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
- if (mPausingActivity == r) {
- if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
- + (timeout ? " (due to timeout)" : " (pause complete)"));
- completePauseLocked(true);
- } else {
- EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
- r.userId, System.identityHashCode(r), r.shortComponentName,
- mPausingActivity != null
- ? mPausingActivity.shortComponentName : "(none)");
- }
- }
- }
ActivityStack.class
[java] view plain copy源碼分析
- private void completePauseLocked(boolean resumeNext) {
- ActivityRecord prev = mPausingActivity;
- if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
-
- if (prev != null) {
- //...
- }
-
- if (resumeNext) {
- final ActivityStack topStack = mStackSupervisor.getFocusedStack();
- if (!mService.isSleepingOrShuttingDown()) {
- mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
- } else {
- mStackSupervisor.checkReadyForSleepLocked();
- ActivityRecord top = topStack.topRunningActivityLocked(null);
- if (top == null || (prev != null && top != prev)) {
- // If there are no more activities available to run,
- // do resume anyway to start something. Also if the top
- // activity on the stack is not the just paused activity,
- // we need to go ahead and resume it to ensure we complete
- // an in-flight app switch.
- mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
- }
- }
- }
-
- if (prev != null) {
- //...
- }
-
- // Notfiy when the task stack has changed
- mService.notifyTaskStackChangedLocked();
- }
ActivityStackSupervisor.class
[java] view plain copyui
- boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
- Bundle targetOptions) {
- if (targetStack == null) {
- targetStack = getFocusedStack();
- }
- // Do targetStack first.
- boolean result = false;
- if (isFrontStack(targetStack)) {
- result = targetStack.resumeTopActivityLocked(target, targetOptions);
- }
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- if (stack == targetStack) {
- // Already started above.
- continue;
- }
- if (isFrontStack(stack)) {
- //調用 ActivityStack.resumeTopActivityLocked(null)方法正式啓動目標Activity
- stack.resumeTopActivityLocked(null);
- }
- }
- }
- return result;
- }
ActivityStack.classthis
[java] view plain copy
- final boolean resumeTopActivityLocked(ActivityRecord prev) {
- return resumeTopActivityLocked(prev, null);
- }
-
- final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
- if (mStackSupervisor.inResumeTopActivity) {
- // Don't even start recursing.
- return false;
- }
-
- boolean result = false;
- try {
- // Protect against recursion.
- mStackSupervisor.inResumeTopActivity = true;
- if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
- mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
- mService.updateSleepIfNeededLocked();
- }
- result = resumeTopActivityInnerLocked(prev, options);
- } finally {
- mStackSupervisor.inResumeTopActivity = false;
- }
- return result;
- }
ActivityStack.class
[java] view plain copy
- final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
- if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
- //...
- if (next == null) {
- //...
- }
-
- // If the top activity is the resumed one, nothing to do.
- if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
- mStackSupervisor.allResumedActivitiesComplete()) {
- //...
- }
-
- final TaskRecord nextTask = next.task;
- if (prevTask != null && prevTask.stack == this &&
- prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
- //...
- }
- //...
- ActivityStack lastStack = mStackSupervisor.getLastStack();
- if (next.app != null && next.app.thread != null) {
- //...
-
- } else {
- // Whoops, need to restart this activity!
- if (!next.hasBeenLaunched) {
- next.hasBeenLaunched = true;
- } else {
- //...
- }
- if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);
- mStackSupervisor.startSpecificActivityLocked(next, true, true);
- }
-
- if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
- return true;
- }
若是上面不能直接resume已有的Activity對象,那麼接下來就要判斷目標Activity對應的進程是否存在。
ActivityStackSupervisor.class
[java] view plain copy
- void startSpecificActivityLocked(ActivityRecord r,
- boolean andResume, boolean checkConfig) {
- // Is this activity's application already running?
- ////獲取目標Activity對應的進程對象ProcessRecord app
- ProcessRecord app = mService.getProcessRecordLocked(r.processName,
- r.info.applicationInfo.uid, true);
-
- r.task.stack.setLaunchTime(r);
- //若是目標Activity所在的app進程已經開啓,好比說直接從Activity_A打開Activity_B
- 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.versionCode,
- mService.mProcessStats);
- }
- realStartActivityLocked(r, app, andResume, checkConfig);
- //注意:在這裏return了
- 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.
- }
- //若是目標Activity所在的app進程還未開啓,若是是從Launcher啓動一個新的APP,則會調用此句(不會執行上面的if)
- mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
- "activity", r.intent.getComponent(), false, false, true);
- }
Activity_A打開Activity_B會執行if (app != null && app.thread != null) 中的realStartActivityLocked(r, app, andResume, checkConfig),由於已經目標Activity對應的進程已經開啓了,其實啓動目標進程以後(mService.startProcessLocked),仍是會調用realStartActivityLocked,這裏也順便去看一看是怎麼啓動目標進程的。
追蹤ActivityManagerService.startProcessLocked,發現它會一步一步調用其重載函數(不貼代碼了),最後調用關鍵的
Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
經過Process.start啓動一個新的應用進程,而且應用進程會從ActivityThread類 的 main()方法中開始執行,轉了一圈,又回到了ActivityThread(上面說過:ActivityThread,該類爲應用程序的主線程類,全部的APK程序都有且僅有一個ActivityThread類 ,程序的入口爲該類中的static main()函數)。
ActivityThread.class
[java] view plain copy
- public static void main(String[] args) {
- SamplingProfilerIntegration.start();
- Looper.prepareMainLooper();
- ActivityThread thread = new ActivityThread();
- thread.attach(false);
- //...
- Looper.loop();
- //...
- }
調用prepareMainLooper()在 U I線程建立一個消息隊列(MessageQueue),Looper.loop()讓消息循環。
H (Handler)和ApplicationThread則是在ActivityThread的初始化的時候建立的
[java] view plain copy
- final ApplicationThread mAppThread = new ApplicationThread();
- final Looper mLooper = Looper.myLooper();
- final H mH = new H();
前面說過,ApplicationThread它是一個Binder對象,負責接收遠程AmS的 IPC 調用,接收到調用後,則通 過Handler把消息發送到消息隊列,U I主線程會異步地從消息隊列中取出消息並執行相應操做,好比 start、 stop、pause 等 。
跟蹤main方法中的thread.attach(false)
[java] view plain copy
- private void attach(boolean system) {
- sCurrentActivityThread = this;
- mSystemThread = system;
- if (!system) {
- //...
- try {
- mgr.attachApplication(mAppThread);
- } catch (RemoteException ex) {
- // Ignore
- }
- //...
- } else {
- //...
- }
-
- //...
- ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
- //...
- });
- }
能夠看到,這裏 mgr.attachApplication(mAppThread)把ActivityThread初始化時建立的mAppThread做爲參數傳遞過去
再耐心地繼續跟蹤:
ActivityManagerService.class
[java] view plain copy
- @Override
- public final void attachApplication(IApplicationThread thread) {
- synchronized (this) {
- int callingPid = Binder.getCallingPid();
- final long origId = Binder.clearCallingIdentity();
- attachApplicationLocked(thread, callingPid);
- Binder.restoreCallingIdentity(origId);
- }
- }
ActivityManagerService.class
[java] view plain copy
- private final boolean attachApplicationLocked(IApplicationThread thread,
- int pid) {
-
- // 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;
- if (pid != MY_PID && pid >= 0) {
- synchronized (mPidsSelfLocked) {
- app = mPidsSelfLocked.get(pid);
- }
- } else {
- app = null;
- }
-
- if (app == null) {
- //...
- return false;
- }
-
-
-
- //...
-
- if (localLOGV) Slog.v(
- TAG, "New app record " + app
- + " thread=" + thread.asBinder() + " pid=" + pid);
- try {
- //...
- //經過thread.bindApplication調用ActivityThread.handleBindApplication,Binder機制
- thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
- profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
- app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
- isRestrictedBackupMode || !normalMode, app.persistent,
- new Configuration(mConfiguration), app.compat,
- getCommonServicesLocked(app.isolated),
- mCoreSettingsObserver.getCoreSettingsLocked());
- updateLruProcessLocked(app, false, null);
- app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
- } catch (Exception e) {
- //...
- return 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;
- }
經過thread.bindApplication調用ActivityThread.handleBindApplication,Binder機制
ActivityThread.class
[java] view plain copy
- private void handleBindApplication(AppBindData data) {
- mBoundApplication = data;
- mConfiguration = new Configuration(data.config);
- mCompatConfiguration = new Configuration(data.config);
-
- //...
-
- if (data.instrumentationName != null) {
- InstrumentationInfo ii = null;
- try {
- ii = appContext.getPackageManager().
- getInstrumentationInfo(data.instrumentationName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- }
- if (ii == null) {
- throw new RuntimeException(
- "Unable to find instrumentation info for: "
- + data.instrumentationName);
- }
-
- mInstrumentationPackageName = ii.packageName;
- mInstrumentationAppDir = ii.sourceDir;
- mInstrumentationSplitAppDirs = ii.splitSourceDirs;
- mInstrumentationLibDir = ii.nativeLibraryDir;
- mInstrumentedAppDir = data.info.getAppDir();
- mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
- mInstrumentedLibDir = data.info.getLibDir();
-
- ApplicationInfo instrApp = new ApplicationInfo();
- instrApp.packageName = ii.packageName;
- instrApp.sourceDir = ii.sourceDir;
- instrApp.publicSourceDir = ii.publicSourceDir;
- instrApp.splitSourceDirs = ii.splitSourceDirs;
- instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
- instrApp.dataDir = ii.dataDir;
- instrApp.nativeLibraryDir = ii.nativeLibraryDir;
- LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
- appContext.getClassLoader(), false, true, false);
- ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
-
- try {
- java.lang.ClassLoader cl = instrContext.getClassLoader();
- //Instrumentation的初始化,一個應用程序中只有一個Instrumentation對象,每一個Activity內部都有一個該對象的引用,初始化完成以後,幫助管理Activity生命週期的回調。
- mInstrumentation = (Instrumentation)
- cl.loadClass(data.instrumentationName.getClassName()).newInstance();
- } catch (Exception e) {
- throw new RuntimeException(
- "Unable to instantiate instrumentation "
- + data.instrumentationName + ": " + e.toString(), e);
- }
-
- mInstrumentation.init(this, instrContext, appContext,
- new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
- data.instrumentationUiAutomationConnection);
- //...
-
- } else {
- mInstrumentation = new Instrumentation();
- }
-
- if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
- dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
- }
-
- // Allow disk access during application and provider setup. This could
- // block processing ordered broadcasts, but later processing would
- // probably end up doing the same disk access.
- final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
- try {
- //...
-
- // Do this after providers, since instrumentation tests generally start their
- // test thread at this point, and we don't want that racing.
- try {
- //App
- mInstrumentation.onCreate(data.instrumentationArgs);
- }
- catch (Exception e) {
- throw new RuntimeException(
- "Exception thrown in onCreate() of "
- + data.instrumentationName + ": " + e.toString(), e);
- }
-
- try {
- //回調Application的onCreate方法
- mInstrumentation.callApplicationOnCreate(app);
- } catch (Exception e) {
- if (!mInstrumentation.onException(app, e)) {
- throw new RuntimeException(
- "Unable to create application " + app.getClass().getName()
- + ": " + e.toString(), e);
- }
- }
- } finally {
- StrictMode.setThreadPolicy(savedPolicy);
- }
- }
前面提到的Instrumentation就是在裏面初始化的,初始化完成以後,幫助管理Activity生命週期的回調。
再接着分析ActivityManagerService.attachApplicationLocked方法中的mStackSupervisor.attachApplicationLocked(app)
[java] view plain copy
- boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
- final String processName = app.processName;
- boolean didSomething = false;
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- if (!isFrontStack(stack)) {
- continue;
- }
- ActivityRecord hr = stack.topRunningActivityLocked(null);
- if (hr != null) {
- if (hr.app == null && app.uid == hr.info.applicationInfo.uid
- && processName.equals(hr.processName)) {
- try {
- //調用了realStartActivityLocked
- if (realStartActivityLocked(hr, app, true, true)) {
- didSomething = true;
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "Exception in new application when starting activity "
- + hr.intent.getComponent().flattenToShortString(), e);
- throw e;
- }
- }
- }
- }
- }
- if (!didSomething) {
- ensureActivitiesVisibleLocked(null, 0);
- }
- return didSomething;
- }
看到沒有,這裏仍然調用了realStartActivityLocked,再重複一下:
若是目標進程還處於活動狀態,因此只須要讓目標進程再建立一個指定Activity的對象並執行之便可,調用realStartActivityLocked,不然,若是目標進程還不存在,則須要首先啓動目標進程,最後仍是要調用realStartActivityLocked
仍是得繼續追蹤ActivityStackSupervisor中的realStartActivityLocked
ActivityStackSupervisor.class
[java] view plain copy
- final boolean realStartActivityLocked(ActivityRecord r,
- ProcessRecord app, boolean andResume, boolean checkConfig)
- throws RemoteException {
-
- r.startFreezingScreenLocked(app, 0);
- if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
- //setAppVisibility(true/false), 其做 用 是 告 訴WMS指定的窗口是否能夠被顯示,這裏爲true,表示能夠被顯示
- mWindowManager.setAppVisibility(r.appToken, true);
- //...
- try {
- //...
- app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
- //調用ApplicationThread.scheduleLaunchActivity
- app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
- System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
- r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
- r.icicle, r.persistentState, results, newIntents, !andResume,
- mService.isNextTransitionForward(), profilerInfo);
-
- if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
- //...
- }
-
- } 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.
- app.activities.remove(r);
- throw e;
- }
-
- //...
-
- // Launch the new version setup screen if needed. We do this -after-
- // launching the initial activity (that is, home), so that it can have
- // a chance to initialize itself while in the background, making the
- // switch back to it faster and look better.
- if (isFrontStack(stack)) {
- mService.startSetupActivityLocked();
- }
-
- // Update any services we are bound to that might care about whether
- // their client may have activities.
- mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
-
- return true;
- }
setAppVisibility(true/false), 其做 用是告訴WMS指定的窗口是否能夠被顯示,這裏爲true,表示能夠被顯示。
繼續追蹤ApplicationThread.scheduleLaunchActivity,還記得前面調用過ApplicationThread.schedulePauseActivity吧!
ApplicationThread.class
[java] view plain copy
- public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
- ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
- String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
- PersistableBundle persistentState, List<ResultInfo> pendingResults,
- List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
- ProfilerInfo profilerInfo) {
-
- updateProcessState(procState, false);
-
- ActivityClientRecord r = new ActivityClientRecord();
-
- r.token = token;
- r.ident = ident;
- r.intent = intent;
- r.referrer = referrer;
- r.voiceInteractor = voiceInteractor;
- r.activityInfo = info;
- r.compatInfo = compatInfo;
- r.state = state;
- r.persistentState = persistentState;
-
- r.pendingResults = pendingResults;
- r.pendingIntents = pendingNewIntents;
-
- r.startsNotResumed = notResumed;
- r.isForward = isForward;
-
- r.profilerInfo = profilerInfo;
-
- updatePendingConfiguration(curConfig);
-
- sendMessage(H.LAUNCH_ACTIVITY, r);
- }
說明:scheduleLaunchActivity()方 法根據參數構造出一個本地ActivityRecord數據類 ,ActivityThread內部會爲每個Activity創 建 一 個 ActivityRecord對象,並使用這些數據對象來管理Activity。
最後經過 sendMessage(H.LAUNCH_ACTIVITY, r)去掉用handleLaunchActivity(),在handleLaunchActivity裏面再調用到 performLaunchActivity()和 handleResumeActivity()
H類前面已經解釋過了,再來看看 handleLaunchActivity
ActivityThread.class
[java] view plain copy
- private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
- // If we are getting ready to gc after going to the background, well
- // we are back active so skip it.
- unscheduleGcIdler();
- mSomeActivitiesChanged = true;
-
- if (r.profilerInfo != null) {
- mProfiler.setProfiler(r.profilerInfo);
- mProfiler.startProfiling();
- }
-
- // Make sure we are running with the most recent config.
- handleConfigurationChanged(null, null);
-
- if (localLOGV) Slog.v(
- TAG, "Handling launch of " + r);
-
- // Initialize before creating the activity
- WindowManagerGlobal.initialize();
- //獲得一個Activity實例,在裏面會執行onCreate方法
- Activity a = performLaunchActivity(r, customIntent);
-
- if (a != null) {
- r.createdConfig = new Configuration(mConfiguration);
- Bundle oldState = r.state;
- // 調用目標activity的onResume,追蹤源碼會發現 目標activity的onStart在裏面會先於onResume調用
- handleResumeActivity(r.token, false, r.isForward,
- !r.activity.mFinished && !r.startsNotResumed);
-
- if (!r.activity.mFinished && r.startsNotResumed) {
- // The activity manager actually wants this one to start out
- // paused, because it needs to be visible but isn't in the
- // foreground. We accomplish this by going through the
- // normal startup (because activities expect to go through
- // onResume() the first time they run, before their window
- // is displayed), and then pausing it. However, in this case
- // we do -not- need to do the full pause cycle (of freezing
- // and such) because the activity manager assumes it can just
- // retain the current state it has.
- try {
- r.activity.mCalled = false;
- //這裏再次去居然再次調用了callActivityOnPause?其實在前面的performPauseActivity方法中已經調用了此方法,Activity_A已經執行了OnPause
- mInstrumentation.callActivityOnPause(r.activity);
- // We need to keep around the original state, in case
- // we need to be created again. But we only do this
- // for pre-Honeycomb apps, which always save their state
- // when pausing, so we can not have them save their state
- // when restarting from a paused state. For HC and later,
- // we want to (and can) let the state be saved as the normal
- // part of stopping the activity.
- if (r.isPreHoneycomb()) {
- r.state = oldState;
- }
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString() +
- " did not call through to super.onPause()");
- }
-
- } catch (SuperNotCalledException e) {
- throw e;
-
- } catch (Exception e) {
- if (!mInstrumentation.onException(r.activity, e)) {
- throw new RuntimeException(
- "Unable to pause activity "
- + r.intent.getComponent().toShortString()
- + ": " + e.toString(), e);
- }
- }
- r.paused = true;
- }
- } else {
- // If there was an error, for any reason, tell the activity
- // manager to stop us.
- try {
- ActivityManagerNative.getDefault()
- .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
- } catch (RemoteException ex) {
- // Ignore
- }
- }
- }
繼續追蹤performLaunchActivity
ActivityThread.class
[java] view plain copy
- private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
- // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
- //...
- Activity activity = null;
- try {
- java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
- 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 {
- Application app = r.packageInfo.makeApplication(false, mInstrumentation);
- //...
- if (activity != null) {
- //...
- //在這裏終於開始調用目標Activity的OnCreate方法了
- if (r.isPersistable()) {
- mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
- } else {
- mInstrumentation.callActivityOnCreate(activity, r.state);
- }
- //...
- if (!r.activity.mFinished) {
- //這裏調用Activity_B的nRestoreInstanceState方法,獲取保存在Bundle中的信息
- 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);
- }
- }
- //...
- }
- //...
-
- } catch (SuperNotCalledException e) {
- throw e;
-
- } catch (Exception e) {
- //...
- }
-
- return activity;
- }
Instrumentation.callActivityOnCreate會調用activity.performCreate(icicle, persistentState),activity.performCreate又會其調用onCreate方法(不貼代碼了)。
到這裏,Activity_B已經執行了onCreate方法,已經走完了Activity_A的onPause-->Activity_B的onCreate生命週期回調的流程。
performLaunchActivity()方法返回後,執行ActivityThread.handleResumeActivity
ActivityThread.class
[java] view plain copy
- final void handleResumeActivity(IBinder token,
- boolean clearHide, boolean isForward, boolean reallyResume) {
- // 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
- //在performResumeActivity裏面調用了目標Activity_B的 onStart和onResume()方法,後面會追蹤源碼
- ActivityClientRecord r = performResumeActivity(token, clearHide);
-
- if (r != null) {
- final Activity a = r.activity;
- //...
-
- if (!r.activity.mFinished && willBeVisible
- && r.activity.mDecor != null && !r.hideForNow) {
- //...
- if (r.activity.mVisibleFromClient) {
- //過r.activity.makeVisible()調用目標Activity_B的 makeVisible()函數,該函數其內部又會展轉和WmS進行各類調用,並最終致使Activity包含 的DecorView顯示到屏幕上
- r.activity.makeVisible();
- }
- }
-
- if (!r.onlyLocalRequest) {
- r.nextIdle = mNewActivities;
- mNewActivities = r;
- if (localLOGV) Slog.v(
- TAG, "Scheduling idle handler for " + r);
- //建立一個Idler對象,並添加到線程消息隊列中,
- Looper.myQueue().addIdleHandler(new Idler());
- }
- //...
-
- } else {
- //...
- }
- }
追蹤performResumeActivity
ActivityThread.class
[java] view plain copy
- public final ActivityClientRecord performResumeActivity(IBinder token,
- boolean clearHide) {
- ActivityClientRecord r = mActivities.get(token);
- if (localLOGV) Slog.v(TAG, "Performing resume of " + r
- + " finished=" + r.activity.mFinished);
- if (r != null && !r.activity.mFinished) {
- if (clearHide) {
- r.hideForNow = false;
- r.activity.mStartedActivity = false;
- }
- try {
- //...
- r.activity.performResume();
-
- //...
- } catch (Exception e) {
- //...
- }
- }
- return r;
- }
繼續看performResume
Activity.class
[java] view plain copy
- final void performResume() {
- //目標Activity的OnRestart和Onstart都在裏面
- performRestart();
-
- mFragments.execPendingActions();
-
- mLastNonConfigurationInstances = null;
-
- mCalled = false;
- // mResumed is set by the instrumentation
- // 調用了目標Activity的 onOnResume方法
- mInstrumentation.callActivityOnResume(this);
- if (!mCalled) {
- throw new SuperNotCalledException(
- "Activity " + mComponent.toShortString() +
- " did not call through to super.onResume()");
- }
-
- // Now really resume, and install the current status bar and menu.
- mCalled = false;
-
- mFragments.dispatchResume();
- mFragments.execPendingActions();
-
- onPostResume();
- if (!mCalled) {
- throw new SuperNotCalledException(
- "Activity " + mComponent.toShortString() +
- " did not call through to super.onPostResume()");
- }
- }
仍是得繼續看performRestart
[java] view plain copy
- final void performRestart() {
- mFragments.noteStateNotSaved();
-
- if (mStopped) {
- mStopped = false;
- if (mToken != null && mParent == null) {
- WindowManagerGlobal.getInstance().setStoppedState(mToken, false);
- }
-
- //...
-
- mCalled = false;
- //這裏調用OnRestart方法
- mInstrumentation.callActivityOnRestart(this);
- if (!mCalled) {
- throw new SuperNotCalledException(
- "Activity " + mComponent.toShortString() +
- " did not call through to super.onRestart()");
- }
- //目標Activity的onStart在這裏面
- performStart();
- }
- }
[java] view plain copy
- final void performStart() {
- //...
- // 目標Activity的onStart在這裏執行
- mInstrumentation.callActivityOnStart(this);
- if (!mCalled) {
- throw new SuperNotCalledException(
- "Activity " + mComponent.toShortString() +
- " did not call through to super.onStart()");
- }
- //...
- }
Instrumentation.class
[java] view plain copy
- public void callActivityOnStart(Activity activity) {
- activity.onStart();
- }
看到了activity.onStart()[java] view plain copy
- public void callActivityOnResume(Activity activity) {
- activity.mResumed = true;
- activity.onResume();
-
- if (mActivityMonitors != null) {
- synchronized (mSync) {
- final int N = mActivityMonitors.size();
- for (int i=0; i<N; i++) {
- final ActivityMonitor am = mActivityMonitors.get(i);
- am.match(activity, activity, activity.getIntent());
- }
- }
- }
- }
看到了activity.onResume()
至此,從已經走到了Activity_B生命週期的onResume方法。
源碼分析已經完成了Activity_A.onPause()--Activity_B.onCreate()--Activity_B.onStart()--Activity_B.onResume(),期間還看到了Activity的onSaveInstanceState(),OnRestoreInstanceState(),OnRestart()方法。
還有最後Activity_A的onStop方法沒有看到,繼續看源碼吧!
回到ActivityThread的handleResumeActivity方法,裏面的r.activity.makeVisible()去調用目標Activity_B的 makeVisible()函數,該函數其內部又會展轉和WmS進行各類調用,並最終致使Activity包含 的DecorView顯示到屏幕上(有待研究)。
handleResumeActivity方法中還有一句Looper.myQueue().addIdleHandler(new Idler()),建立一個Idler對象,並添加到線程消息隊列中,而 Idler類的內部處理函數則是調用WmS的 activityldle()方法在該函數的內部則會展轉調用到stopActivityLocked()方法。
ActivityStack.class
[java] view plain copy
- final void stopActivityLocked(ActivityRecord r) {
- //...
- if (r.app != null && r.app.thread != null) {
- adjustFocusedActivityLocked(r, "stopActivity");
- r.resumeKeyDispatchingLocked();
- try {
- //...
- //這裏調用setAppVisibility(r.appToken, false)隱藏Activity_A
- if (!r.visible) {
- mWindowManager.setAppVisibility(r.appToken, false);
- }
- //這裏則是調用ActivityThread.scheduleStopActivity
- r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
- //...
- Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
- mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
- } catch (Exception e) {
- //...
- }
- }
- }
又回到了ActivityThread
ActivityThread.class
[java] view plain copy
- public final void scheduleStopActivity(IBinder token, boolean showWindow,
- int configChanges) {
- sendMessage(
- showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
- token, 0, configChanges);
- }
告知H,執行 handleStopActivity,又會調用ActivityThread的performStopActivityInner,接着執行r.activity.performStop()調用Activity的performStop
Activity.class
[java] view plain copy
- final void performStop() {
- mDoReportFullyDrawn = false;
- //...
-
- if (!mStopped) {
- //...
- //這裏Activity_A的OnStop方法
- mInstrumentation.callActivityOnStop(this);
- if (!mCalled) {
- throw new SuperNotCalledException(
- "Activity " + mComponent.toShortString() +
- " did not call through to super.onStop()");
- }
-
- //...
- mStopped = true;
- }
- mResumed = false;
- }
Instrumentation.class
[java] view plain copy
- public void callActivityOnStop(Activity activity) {
- activity.onStop();
- }
最後調用了activity.onStop()
至此,從Activity_A到Activity_B,分別經歷的生命週期執行過程和順序 走通了!!!!
Activity_A.onPause()--Activity_B.onCreate()--Activity_B.onStart()--Activity_B.onResume()--Activity_A.onStop()。