Activity生命周期的回调,你应该知道得很多其它!--Android源代码剖析(下)
接着上一篇继续去追踪Activity_B生命周期回调源代码。
继续分析,在performPauseActivity方法中,回调了Activity的两个操作函数:
一
个是用于保存状态的onSaveInstanceState(),还有一个就是onPause()
,这里你应该了解onPause和onSaveInstanceState的调用顺序了,这里看来OnSaveInstanceState是先于onPause的调用的,可是打印的Log显示onSaveInstanceState在onPause之后,在onStop之前调用(不明确)。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
最后r.state置为true。
当 AmS通知当前Activity暂停后,AmS会马上返回,而在目标进程中则是发送一个暂停的消息,处理完该暂停消息后,目标进程会调用AmS的 activityPaused(),报 告 AMS自己已经暂停完成,然后运行ActivityManagerNative.getDefault().activityPaused(token)
从而AMS将開始启动真正的Activity。
前面说过。ActivityManagerNative.getDefault().activityPaused的动作运行者是ActivityManagerService.activityPaused
ActivityManagerService.class
- 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
- 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
- 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
- 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.class
- 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
- 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
- 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,发现它会一步一步调用其重载函数(不贴代码了),最后调用关键的
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
- 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的初始化的时候创建的
- 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)
- 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
- @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
- 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
- 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)
- 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
- 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
- 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
- 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
- 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
- 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
- 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;
- }
- 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
- 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();
- }
- }
- final void performStart() {
- //...
- // 目标Activity的onStart在这里运行
- mInstrumentation.callActivityOnStart(this);
- if (!mCalled) {
- throw new SuperNotCalledException(
- "Activity " + mComponent.toShortString() +
- " did not call through to super.onStart()");
- }
- //...
- }
- public void callActivityOnStart(Activity activity) {
- activity.onStart();
- }
看到了activity.onStart()
- 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_A.onPause()--Activity_B.onCreate()--Activity_B.onStart()--Activity_B.onResume(),期间还看到了Activity的onSaveInstanceState(),OnRestoreInstanceState()。OnRestart()方法。
makeVisible()函数,该函数其内部又会辗转和WmS进行各种调用。并最终导致Activity包括
的DecorView显示到屏幕上(有待研究)。
Idler()),创建一个Idler对象,并加入到线程消息队列中。而 Idler类的内部处理函数则是调用WmS的 activityldle()方法在该函数的内部则会辗转调用到stopActivityLocked()方法。
ActivityStack.class
- 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
- 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
- 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
- public void callActivityOnStop(Activity activity) {
- activity.onStop();
- }
最后调用了activity.onStop()
至此,从Activity_A到Activity_B,分别经历的生命周期运行过程和顺序
走通了!!。!
Activity生命周期的回调,你应该知道得很多其它!--Android源代码剖析(下)的更多相关文章
- android官方Api 理解Activity生命周期的回调机制(适合有基础的人看)
原文地址:http://www.android-doc.com/training/basics/activity-lifecycle/starting.html#lifecycle-states 此处 ...
- Android全面解析之Activity生命周期
前言 很高兴遇见你~ 欢迎阅读我的文章. 关于Activity生命周期的文章,网络上真的很多,有很多的博客也都讲得相当不错,可见Activity的重要性是非常高的.事实上,我猜测每个android开发 ...
- Activity生命周期以及启动模式对生命周期的影响(二)
前面一篇文章概述了Android四大组件之一的Activity生命周期方法的调用先后顺序,但对于非标准启动模式下Activity被多次调用时的一些生命周期方法并未详细阐述,现在针对该情况着重记录. 现 ...
- Android Activity生命周期与启动模式
Activity的完整生命周期如下图: Activity的加载模式有四种: standard: 标准模式,默认的加载模式,每次通过这种模式启动目标Acitivity,都创建一个新的实例,并将该Acti ...
- Activity生命周期(深入理解)
今天看到一篇大神总结Activity的文章,内容甚为详细,特此转载http://www.cnblogs.com/lwbqqyumidi/p/3769113.html Android官方文档和其他不少资 ...
- Android Activity生命周期详讲
管理 Activity 生命周期 通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要. Activity 的生命周期会直接受到 Activity 与其他 Activit ...
- Android总结篇系列:Activity生命周期
Android官方文档和其他不少资料都对Activity生命周期进行了详细介绍,在结合资料和项目开发过程中遇到的问题,本文将对Activity生命周期进行一次总结. Activity是由Activit ...
- Android体系结构及activity生命周期
Android的系统架构采用了分层架构的思想,如图1所示.从上层到底层共包括四层,分别是应用程序程序层.应用框架层.系统库和Android运行时和Linux内核 Android的系统架构图 每层 ...
- Android学习整理之Activity生命周期篇
一.Activity生命周期说明 Activity的四种状态: ⒈活动状态(Active or Running):也称为运行状态,处于Activity栈顶,在用户界面中最上层,完全能被用户看到,能 ...
随机推荐
- 今日SGU 5.2
SGU123 题意:求和 收获:无 #include<bits/stdc++.h> #define de(x) cout<<#x<<"="< ...
- 【例题 8-12 UVA-12627】Erratic Expansion
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 规律+递归题 f[k][i] k时刻前i行的红气球个数 i<=2^(k-1) f[k][i] = 2*f[k-1][i]; i ...
- 【CS Round #39 (Div. 2 only) B】Circle Elimination
[Link]:https://csacademy.com/contest/round-39/task/circle-elimination/ [Description] [Solution] 把n个点 ...
- 漫话Unity(二)
三.Unity编辑器介绍 Unity是一个商业级的3d游戏引擎.一个引擎的专业程度事实上并非体如今它多么牛b 的次世代效果,说实话那些效果即便你会用也不敢用.由于没有哪个手机是次世代的. 游戏引擎的专 ...
- 负载均衡器&http正向代理
透明的负载均衡器&http正向代理 * master-workers架构,http正向代理由独立的dns请求以及缓冲进程 * 使用epoll(ET)模式,採用全异步方式(双缓存,实现双向同一 ...
- 深入理解javascript之原型
理解原型 原型是一个对象.其它对象能够通过它实现属性继承. 不论什么一个对象都能够成为继承,全部对象在默认的情况下都有一个原型.由于原型本身也是对象,所以每一个原型自身又有一个原型. 不论什么一个对象 ...
- eclipse-ubuntu14.04图标替换不掉的问题
今天安装14.04的时候,遇到了一个问题.就是eclipse安装好以后,发现需要配置ADT,老是配置失败.后来实在没有办法了,所以就把这个eclipse跟删除了(当时它并没有安装,而是仅仅解压以后双击 ...
- WebService三大基本元素 SOAP WSDL UDDI
转自:https://blog.csdn.net/hhooong/article/details/51763128 1.SOAP 即 Simple Object AccessProtocol 也就是简 ...
- echarts tooltip提示框 自定义小圆点(颜色、形状和大小等等)
项目是拿 echarts + 百度地图 来做可视化界面,现在到收尾阶段慢慢优化. 先附代码: formatter: function(params) { var result = '' params. ...
- 【Todo】Zookeeper系列文章
http://nileader.blog.51cto.com/1381108/1068033