1.1 启动Activity的时候的特殊情况
一般来说,用户打开新的Activity或者切换到桌面的时候,回调如下:
onPause->onStop。
但是,如果Activity采用的是透明主题,那么当前的Activity是不会回调onStop的。
1.2 被回收的Activity再次启动
当Activity被系统回收了以后再次打开,生命周期方法回调过程还是和第一次打开的一样,但是,这只是说生命周期方法一样,这不代表所有的过程都一样。
1.3 Activity生命周期的对称性
从整个生命周期来说,onCreate对应于onDestory,onResume对应onPause ,onStart对应onRestart.其中,前者只能有一次调用,而后者可以多次调用。
1.4 onResume和onStart,onPause和onStop看似相似,却有不同
onStart和onResume,onPause和onStop从描述上看是差不多的,但是,却是有着一些实质性的不同。
这里面实质性的不同,就是他们所处的生命周期的不同,onStart、onStop表示的是,Activity是否可见,而onResume、onPause则是从是否运行在前台的角度来处理的,从可靠性来说,onPause是比onStop更加可靠的。
1.5 不同Activity的onResume和onPause谁先谁后?
假设当前Activity为A,接下来要打开一个新的ActivityB,那么B的onResume和A的onPause哪个先执行呢?
这个需要从Activity源码那边开始入手,Activity的启动过程,涉及到了Instrumentation、ActivityThread和ActivityManagerService(AMS).
Activity的启动请求会通过Instructmentation来处理,然后Instructmentation通过Biner向AMS发出请求,AMS内部维护着一个ActivityStack,并且负责栈内的Activity的状态同步,AMS通过ActivityThread去同步Activity的状态,完成生命周期方法的调用。
在ActivityStatck(com.android.server.am包中)中的resumeTopActivityInnerLocked方法中,有这样一段代码:
// We need to start pausing the current activity so the top one
// can be resumed...
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);
if (mResumedActivity != null) {
pausing = true;
startPausingLocked(userLeaving, false);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
}
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
"resumeTopActivityLocked: Skip resume: need to start pausing");
// At this point we want to put the upcoming activity's process
// at the top of the LRU list, since we know we will be needing it
// very soon and it would be a waste to let it get killed if it
// happens to be sitting towards the end.
if (next.app != null && next.app.thread != null) {
// No reason to do full oom adj update here; we'll let that
// happen whenever it needs to later.
mService.updateLruProcessLocked(next.app, false, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
从上述代码可以看出,在新Activity启动之前,栈顶的Activity需要先onPause才会启动新的Activity.最终,在ActivityStatckSupervisor中的realStartActivityLocked方法毁调用下面这个代码:
a
pp.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration), r.compat,
app.repProcState, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
上面代码中的app类型为:
ProcessRecord 。
查看ProcessRecord 中thread的代码:
IApplicationThread thread; // the actual proc... may be null only if
// 'persistent' is true (in which case we
// are in the process of launching the app)
可以知道,类型为IApplicationThread,上面说具体实现就是在App运行的进程中,那么可以知道这个代码的具体实现就是在ActivityThread,所以实际上调用的是ActivityThread的scheduleLauchActivity方法,而scheduleLauchActivity方法最终会完成新Activity的onCreate、onStart、onResume的调用过程,
具体代码如下:
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
int procState, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
其中:
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
上面这一行会通过一个类型为:H(命名我mH)的Handler对象接收到消息以后,在handlerLaunchActivity方法中来实现新Activity的onCreate、onStart、onResume。
所以结论得出:旧的Activity先onPause,新的Activity再启动。
1.6 关于onPause的解释:
Android官方文档在onPause中标注了如下:
When activity B is launched in front of activity A, this callback will
be invoked on A. B will not be created until A's {@link #onPause} returns,
so be sure to not do anything lengthy here.
意思就是不要在onPause中做耗时的操作,因为新的Activity会在onPause以后才开始显示到前台。因此耗时操作应该放在onStop中,(onStop不会影响新的Activity的显示)onPause适合做一些保存应用当前的运行数据、如果没有足够多的资源去启动新的Activity那么更要持久化数据,并且在这里最好暂停一些动画啊等消耗CPU资源的操作,使得下一个Activity可以快速启动起来。或者关闭一些唯一的单独的资源访问接口,比如说关闭调用相机。
本文参考
任玉刚先生的《Anroid开发艺术探索》书和官方文档。