(借鉴自Android开发艺术探索)
正常情况
onCreate
表示Activity正在被创建
onRestart
表示Activity正在被重新启动,一般当Activity从不可见到可见,这个方法会被调用
onStart
表示Activity正在被启动,这个时候Activity的界面已经有了(可以认为是可见了,只不过还没有让用户看到)
onResume
表示Activity已经完全可见了
onPause
表示Activity正在停止
onStop
表示Activity即将停止
onDestory
表示Activity即将被销毁,这里适合做一些回收工作
其实onPause执行了,这个时候Activity是部分可见的(比如dialog调用后,Activity会处于onPause状态),当你打开一个新的Activity,正常情况下原来的Activity的onPause和onStop会被调用,但是如果说这个新的Activity是透明的话,原来的Activity只会调用onPause,而不会调用onStop。
启动Activity的请求由Instrumentation来处理,然后Instrumentation通过binder向ActivityManagerService发送请求。ActivityManagerService内部维护一个ActivityStack并负责栈内的Activity的状态同步。AMS通过ActivityThread去同步Activity的状态从而完成生命周期方法的调用。
看一下ActivityStack的resumeTopActivityInnerLocked方法
// We need to start pausing the current activity so the top one can be resumed... final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0; boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause); if (mResumedActivity != null) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause); }startPausingLocked是停止当前处于Resume状态的Activity的方法。所以我们得知,当当前栈顶的Activity执行onPause方法后,新的Activity才可以启动。
为什么说只有在当前栈顶的Activity执行onPause方法后,新的Activity才可以启动呢?我们可以找一下整个流程最后部分的代码。
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);这里的thread查得是IApplicationThread(ActivityThread的子类),而ActivityThread的scheduleLaunchActivity方法最终会完成新Activity的onCreate、onStart、onResume的调用。所以我们得出了上面这个结论: 只有在当前栈顶的Activity执行onPause方法后,新的Activity才可以启动。
看一下scheduleLaunchActivity方法最终调用的handleLaunchActivity方法
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, 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; 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 a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); reportSizeConfigurations(r); Bundle oldState = r.state; handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);Activity a = performLaunchActivity(r, customIntent);这一行完成了Activity的创建
再看看performLaunchActivity方法
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); } }调用了mInstrumentation.newActivity方法利用反射机制创建了Activity(通过类名获取类,再newInstance即可)
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); }沿着performLaunchActivity方法继续往下看
activity和window建立联系(类似于碎片和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);设置主题
if (theme != 0) { activity.setTheme(theme); }回调Activity的onCreate
activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); }调用Activity的onStart(performStart最后也会回调mInstrumentationActivity的onStart)
if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; }看一下Activiy类中的performStart中有一段天杀的代码,运行失败的dialog!(得知了这个是在onStart时出现的)
if (isAppDebuggable) { new AlertDialog.Builder(this). setTitle(appName). setMessage(warning). setPositiveButton(android.R.string.ok, null). setCancelable(false). show(); } else { Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show(); }
除此以外,还有OnRestoreInstanceState的调用
if (!r.activity.mFinished) { 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); } }还有ActivityOnPostCreate的调用
if (r.isPersistable()) { mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnPostCreate(activity, r.state); }performLaunchActivity到这里就没了,这个方法里调用了Activity的onCreate和onStart。而onResume方法要回到handleLaunchActivity方法里继续看。
handleLaunchActivity方法
Activity a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); reportSizeConfigurations(r); Bundle oldState = r.state; handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);就在performLaunchActivity方法的调用下面的一点点。调用了handleResumeActivity方法,在这里调用Activity的onResume。
到这里就找到了onCreate,onStart,onResume了。知道这些流程就已经可以应付大大小小的场合了。(如果感兴趣可以再完全地看一遍更多相关的代码,很好找,也很有趣,也看得懂。)