Activity典型情况下的生命周期

来源:互联网 发布:hopscotch编程 编辑:程序博客网 时间:2024/06/05 10:24

1、典型情况下的生命周期分析
在正常情况下,Activity会经历如下生命周期。

(1) onCreate:表示Activity正在被创建,这是生命周期的第一个方法,在这个方法中,我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源、初始化化Activity所需要数据等。

(2) onRestart:表示Activity正在重新启动,一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart就会调用,这种情形一般时用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity,这时当前的Activity就会暂停,也就是onStop和onPause执行了,接着用户又回到了这个Activity,就会出现这种情况。

(3) onStart:表示Activity正在启动,即将开始,这时Activity已经可见了,但是还没有出现在前台,还无法和用户交互,这个时候其实理解为Activity已经显示出来了,但是我们还看不到。

(4) onResume:表示Activity可见了,并且出现在前台并开始活动。要注意这个和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。

(5) onPause:表示Activity正在停止,正常情况下,紧接着onStop就会调用。在特殊情况下,如果这个时候快速回到当前的Activity,那么onResume会被调用,笔者的理解时,这种情况属于极端情况,用户操作很难重现这一场景,此时可以做一些存储数据的操作,停止动画等工作,但是注意不能太耗时,因为这回影响到新的Activity的显示,onPause必须先执行完,新Acitivity的onResume才会执行。

(6) onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。

(7) onDestory:表示Activity即将被销毁,这是Activity生命周期中最后一个回调,在这里,我们可以做一些回收工作和最终的资源释放。

正常情况下,Activity的常用生命周期就只有上面7个:
这里写图片描述

                            图1-1 Activity生命周期的切换过程

分为以下几种情况

(1)针对一个特定的Activity,第一次启动,回调如下:onCreate->onStart->onResume。

(2)当用户打开新的Activity或者切换到桌面的时候,回调如下: onPause->onStop。如果新的Activity采用了透明主题,那么当前Activity不会回调onStop。

(3)当用户再次回到原Activity时,回调如下: onRestart->onStart->onResume。

(4)当用户按back键回退时,回调如下: onPause->onStop->onDestory。

(5)当Activity被系统回收后在此打开,生命周期方法回调过程和(1)一样,注意只是生命周期方法一样,不代表所有过程一样。

(6)从整个生命周期来说,onCreate和onDestory是配对的,分别标识着Activity的创建和销毁,并且只可能有一次调用,从Activity是否可见来说,onStart和onStop是配对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方法可能被调用多次;从Activity是否在前台来说,onResume和onPause是配对的,随着用户操作或者设备屏幕的点亮和熄灭。

问题1:onStart和onResume、onPause和onStop从描述上来说差不多,对我们来说有什么实上的不同呢?

答:从实际使用上来说,onStart和onResume、onPause和onStop看起来的却差不多,甚至我们可以只保留onStart和onStop。既然如此,那为什么Android系统还要提供看起来重复的接口呢?根据上面的分析,这两个配对的回调分别表示不同的意义,onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台来回调的,除了这种区别,在实际使用中没有其他明显区别。

问题2:假设当前Activity为A,如果这时用户打开一个新的ActivityB,那么B的onResume和A的onPase哪个先执行呢?

答:简单理解,启动Activity的请求会由Instrumentation来处理,然后它通过Binder向AMS发请求,AMS(ActivityManagerService)内部维护着一个ActivityStack并负责栈内的Activity的状态同步,AMS通过ActivityThread去同步Activity的状态从而完成生命周期方法的调用。在ActivityStack中的resumeTopActivityInnerLocked方法中,有这么一段代码:

//We need to start pausing the current activity so the top one
//can be resumed...
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSEING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving,true,dongWaitForPause);
if(mResumedActivity != null){
pausing |= startPausingLocked(userLeaving,false,true,dongWaitForPause);
if(DEBUG_STATES) Slog.d(TAG,"resumeTopActivityLocked:Pausing "+mResumedActivity);
}

从上述代码可以看出,在新的Activity启动之前,栈顶的Activity需要先onPause后,新的Activity才能启动。最终,在ActivityStackSupervisor中的realStartActivityLocked方法会调用如下代码:


app.thread.scheduleLaunchActivity(
new Intent(r.intent),r.appToken,System.identityHashCode(r),
r.info,new Caonfiguration(mService.mConfiguration),
r.compat,r.task.voiceInteractor,app.repProcState,r.icicle,
r.persistenState,results,newIntents,!andResume,mService,isNextTransitionForward(),profilerInfo);

我们知道这个app.thread类型是IApplicationThread,而IApplicationThread的具体实现是ActivityThread种的ApplicationThread。所以这段代码实际上调到了ActivityThread中,即ApplicationThread的scheduleLauchActivity方法,而scheduleLauchActivity方法最终会完成新的Activity的onCreate、onStart、onResume的调用过程,因此可以得出结论是旧的Activity先onPause,然后新的Activity再启动。

至于ApplicationThread的scheduleLaunchActivity方法为什么会完成新Activity的onCreate、onStart、onResume的调用过程,请看下面的代码。scheduleLaunchActivity最终会调用如下方法,而如下方法的确会完成onCreate、onStart、onResume的调用过程。

private void handleLaunchActivity(ActivityClientRecord r,Intent customIntent){//if we are getting ready to go gc after going to the background, well//we are back active so skip itunscheduleGcIdler();mSomeActivityesChanged = true;if(r.profilerInfo!=null){mProfiler.setProfiler(r.profilerInfo);mProfiler.startProfiling();}//Make sure we are running with the most recent confighandleConfigurationChanged(null,null);

//这里Activity被创建出来,其onCreate和onStart会被调用
`Activity a = performLaunchActivity(r,customIntent);

if(a!=null){    r.createdConfig = new Configuration(mConfiguration);    Bundle oldState = r.state;    //这里新的Activtiy的onResume会被调用    handleResumeActivity(r.token,false,r.isForward,!r.activity.mFinished && !   r.startsNotResumed);}

`
Android官方文档对onPause的解释有这么一句:不能再onPause中做重量级的操作,因为必须onPause执行完以后新的Activity才能Resume,onPause和onStop都不能执行耗时操作,尤其是onPause,这也意味着,我们应该尽量在Stop中做操作,从而使得新Activity尽快显示出来并切换到前台。

阅读全文
0 0