Android Activity生命周期管理

来源:互联网 发布:join java 编辑:程序博客网 时间:2024/04/30 11:18

http://blog.csdn.net/thl789/article/details/6628463


本文描述Android中Activity的状态,Activity的状态转换,从而总结了Activity各个生命周期的典型时序。与Android现有框架结合,充分考虑Activity的各个生命周期阶段,应用开发者实现相应的回调接口,只有这样,才能开发出符合框架规范的程序。

 

Activity状态

Activity在Android系统中用一个LIFO机制的Activity栈来管理。当新的Activity[A]启动时,它就被放在了Activity栈的顶端,而进入运行状态,而先前运行的Activity[B]通常就被放在了Activity栈里A的下面。当A退出运行而从Activity栈顶出栈之后,B就成了Activty栈的最上面的Activity,可再次进入前台运行状态。

Activity有三种状态(参考源文档,这里指的是可以保持的状态,states can be static)

Ø RESUMED当Activity在屏幕前台运行时(位于当前任务堆栈的顶部),此时该Activity获得了用户的输入焦点。 这个状态也叫Active或Running状态。

Ø PAUSED当它失去焦点但仍然对用户可见时,它处于暂停状态。此时,在它之上有另外一个Activity。这个Activity也许是透明的,或者未能完全遮蔽全屏,所以被暂停的Activity仍对用户可见。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并连接至窗口管理器)。但当系统处于极低内存的情况下,仍然可以杀死这个Activity。

Ø STOPPED 如果它完全被另一个Activity覆盖是,它处于停止状态。它仍然保留所有的状态和成员信息。然而它不在为用户可见,所以它的窗口将被隐藏。如果其它地方需要内存,则系统经常会杀死这个Activity。

处于PAUSED或STOPPED状态的Activity,可以被移除出内存,移除的先后顺序是先STOPPED状态的,后PAUSED状态的。一般PAUSED状态的Activity也只是在资源极端不足的情况下,它所运行的进程才会被杀掉。是否要移除出内存,还要看它所运行的进程具体状况,具体规则和操作,可参阅[5]。

 

As you'll learn in the following lessons, there are several situations in which an activity transitions between different states that are illustrated in figure 1. However, only three of these states can be static. That is, the activity can exist in one of only three states for an extended period of time:

Resumed
In this state, the activity is in the foreground and the user can interact with it. (Also sometimes referred to as the "running" state.)
Paused
In this state, the activity is partially obscured by another activity—the other activity that's in the foreground is semi-transparent or doesn't cover the entire screen. The paused activity does not receive user input and cannot execute any code.
Stopped
In this state, the activity is completely hidden and not visible to the user; it is considered to be in the background. While stopped, the activity instance and all its state information such as member variables is retained, but it cannot execute any code.

生命周期转换图

下图是根据Android官方提供的Activity状态转换图经过笔者少许更改之后的图。(注意图中,方框内执行的是状态转换的过程,并不是状态,状态如前述,只有三种:RUNNING / PAUSED / STOPPED。在很多文章的描述中,连这点基本的概念都没搞清楚!


(现在可以不理解,但是读完全文,一定要把这张图刻到脑子里!)

 



在上图中,可以从三个阶段关注Activity的生命周期: 

Ø  整个的生命周期,指的是onCreate(Bundle)和onDestroy()之间过程。Activity在onCreate()设置所有的“全局”状态,在onDestroy()释放所有的资源。

Ø 可见的生命周期,指的是onStart()和onStop()之间的过程。在这段时间,可以看到Activity在屏幕上,尽管有可能不在前台,不能和用户交互。在这两个接口之间,需要保持显示给用户的UI数据和资源等。onStart(),onStop()都可以被多次调用,因为Activity随时可以在可见和隐藏之间转换。

Ø 前台的生命周期,指的是onResume()和onPause()之间的过程。在这段时间里,该Activity处于所有 Activity的最上面,获得了用户焦点。Activity可以经常性地在RESUMED和PAUSED状态之间切换,所以在这些接口方法中的代码应该属于非常轻量级的,避免低效的转换而让用户有等待的感觉。

 

由此,我们可以得出下面几个典型的场景

1)   Activity从被装载到运行。则执行顺序为:onCreate() -> onStart()-> onResume();

这是个典型过程,发生在Activity被系统装载运行时。

2)   Activity从运行到暂停,再到继续回到运行。执行顺序为:onPause() -> onResume();

这个过程发生在Activity被别的Activity遮住了部分UI,失去了用户焦点,另外那个Activity退出之后,这个Activity再次重新获得运行。这个过程中该Activity的实例是一直存在。

3)   Activity从运行到停止。执行顺序为:onPause() -> onStop() ;

这个过程发生在Activity的UI完全被别的Activity遮住了,当然也失去了用户焦点。这个过程中Activity的实例仍然存在。比如,当Activity正在运行时,按HOME键,该Activity就会被执行这个过程。

4)   Activity从停止到运行。执行顺序为:onRestart()-> onStart()-> onResume();

处于STOPPED状态并且实例仍然存在的Activity,再次被系统运行时,执行这个过程。这个过程是3的逆过程,只是要先执行onRestart()而重新获得执行。

5)   Activity从运行到销毁。执行顺序为:onPause() -> onStop() -> onDestroy();

这个过程发生在Activity完全停掉并被销毁了,所以该Activity的实例也就不存在了。比如,当Activity正在运行时,按BACK键,该Activity就会被执行这个过程。这个过程可看作是1的逆过程。

6)   被清除出内存的Activity重新运行。执行顺序为:onCreate() -> onStart()-> onResume();

这个过程对用户是透明的,用户并不会知道这个过程的发生,看起来如同1的执行顺序,不同的是如果保存有系统被清除出内出时的信息,会在调用onCreate()时,系统以参数的形式给出,而1中onCreate()的参数为null。

 

管理Activity生命周期

这里说是管理Activity的生命周期,更确切的说应该是参与生命周期的管理,因为Android系统框架已经很好的管理了这其中的绝大部分,应用开发者要做的就是在Android的框架下,在Activity状态转换的各个时点上,做出自己的实现,而实现这些要做的只是在你的Activity子类里面Override这些Activity的方法即可。

下图是Activity生命周期相关的方法。


Activity的实例化与启动

Activity实例化是由Android系统完成,在用户点击执行一个Activity或者另一个Activity需要这个Activity执行的时候,如果该Activity的实例不存在,Android系统都会实例化之,并在该Activity所在进程的主线程中调用该Activity的onCreate()方法,实现Activity实例化时的工作。

所以,Activity::onCreate()是系统实例化Activity时,Activity可做的自身初始化的时机。在这里可以实例化变量,调用Activity::setContentView()设置UI显示内容。

一般的,Activity实例化之后,就要启动该Activity,这样会在该Activity所在进程的主线程中顺序调用Activity的onStart(), onResume()。回头看图一Activity的生命周期的典型时序,一般onStart()在所有的时序中都不是很特别的过程,所以一般不怎么实现。onResume()在暂停继续流程中很重要,后文再讲。

 

下图就是Activity实例化与启动的时序


这里从应用开发者角度来说明问题,暂不考虑Android内部的实现细节,所以各种动作的发起者统一用AndroidSystem来说明,而从Activity这边看过去,所有这些操作也都是异步的。

 

注意

onCreate()在Activity存续期内,只会被调用一次。如生命周期图中的时序6的情形其实是另外又启动了一个Activity的实例,并通过onCreate()的参数传递进先前杀掉的Activtiy里保留的信息。

onStart()可因为已经STOPPED了,再次执行而被调用多次。

onResume()可因为Activity的PAUSED/RESUMED的不停转换,而被频繁调用。

 

Activity的暂停与继续

Activity因为被别的Activity遮住部分UI,并失去焦点而被打断暂停,典型的情况发生在系统进入睡眠或被一个对话框打断的情况。而在被暂停之前,系统会通过onPause()让Activity有保留被暂停前状态的时机。Activity可以在onPause()中,保存所做的修改到永久存储区,停止动画显示,等。onPause()里的操作必须简短并快速返回,因为在onPause()返回之前不会调入其他的Activity运行。

此时Activity因为还有部分UI显示,它通常与Window Manager的链接还在,所以一般UI的修改不需保留。即便在极端的情况下,PAUSED的Activity所在的进程被杀死,那也是极端情况,那种情况下,不可能使Activity的UI显示完整一致。

系统在被唤醒或者打断它的对话框消失之后,会继续运行,此时系统会调用Activity的onResume()方法。在onResume()方法中可以做与onPause()中相对应的事情。

下图是,一个Activity启动同一个进程内另外一个Activity的时序图。它能很好的说明,一个Activity启动时,与另外一个Activity之间的各种PAUSE/RESUME交互过程。


不过千万记得,PAUSE/RESUME是众多Activity状态转换中的一个子集,很多其他的场景也是要走这个过程的。

 

Activity的关闭/销毁与重新运行

Activity被STOP可能是完全被别的Activity覆盖掉了,也可能是用户显式的按了BACK或HOME键。Activity被Stop之前,它的onStop()方法会被提前调用,来做些Stop前的处理。如果处于STOPPED的Activity再次运行,它的onRestart()方法会被调用,这是区分其他调用场景,比较合适的实现处理的地方。

注意,因为处于PAUSED状态的Activity在内存极端不足的情况下,它所在的进程也可能被杀掉,这样onStop()在被杀掉前,不一定会被调用,所以onPause()是比onStop()更合适的保留信息到永久存储区的时机。

Activity被销毁可能是显式的按了BACK键,也可能是处于PAUSED或STOPPED状态,因为内存不足而被杀掉的。还有种情况是配置信息改变(比如屏的方向改变)之后,根据设置需要杀掉所有的Activity(是否关闭还要看Activity自己的配置),再重新运行他们。

被系统隐式杀死的Activity,在被杀死(onStop()调用)之前,一般的会调用onSaveInstanceState()保留该Activity此时的状态信息。该方法中传入Bundle参数,可在此方法中把此时的状态信息写入,系统保留这这些系统。而当该Activty再次被实例化运行时,系统会把保留在Bundler的信息再次以参数形式,通过onCreate()方法传入。

一般,onSaveInstanceState()中保留UI的信息,永久存储的信息最好还是在onPause()中保存。Activity的onSaveInstanceState()已经缺省实现来保留通用View的UI信息,所以不管你保留与否当前Activity的信息,通常都要在onSaveInstanceState()先调用一下super.onSaveInstanceState()保留通用的UI信息。

 

参考资料及进一步阅读

[1] DeveloperGuide Framework Topics – Activities http://developer.android.com/guide/topics/fundamentals/activities.html

[2] ActivityReference http://developer.android.com/reference/android/app/Activity.html

[3] Activitysources Activity.java

[4] Intentand Intent filters http://developer.android.com/guide/topics/intents/intents-filters.html

[5] Processesand Threads http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗狗便秘拉不出来怎么办 2个月幼犬便秘怎么办 狗狗便秘怎么办吃什么 痔疮又痛又痒怎么办 痔疮肉球特别痒怎么办 长了个小痔疮怎么办 产后4天没大便怎么办 7个月孕妇痔疮怎么办 运动完恶心想吐怎么办 跑步后恶心想吐怎么办 肠子不蠕动严重便秘怎么办 怀孕八个月严重便秘怎么办 怀孕七个月便秘严重怎么办 怀孕两个月便秘严重怎么办 3岁宝宝上火便秘怎么办 7个月的宝宝贫血怎么办 9个月婴儿贫血怎么办 肛裂大便有血怎么办 生完宝宝肛门痛怎么办 肛周脓肿出血了怎么办 胃胀怎么办简单的办法 吃多了胃胀难受怎么办 胃窦炎胆汁反流怎么办 怀孕总胆汁酸高怎么办 胃里胆汁反流怎么办 苦胆水吐出来了怎么办 喝多了吐胆汁怎么办 吐出黄水苦水是怎么办 喝酒喝的一直吐怎么办 孕期总胆汁酸高怎么办 孕早期胆汁酸高怎么办 孕妇总胆汁酸高怎么办 宝宝一天吐了6次怎么办 肛周脓肿破了怎么办 肛周脓肿发烧了怎么办 肛周脓肿便血该怎么办 婴儿得肛周脓肿怎么办 水痘长在龟头上怎么办 轻度萎缩性胃炎伴肠化怎么办 肺癌晚期腿肿了怎么办 胸骨剑突按压痛怎么办