(转自:http://blog.csdn.net/flowingflying/article/details/6415323)
Android很大的应用场景是手机,有一些应用具有特别的优先级别,例如电话,同时设备的内存是有限的。因在某些情况下系统将踢走activity,以便是否内存。因此在开发过程中,我们需要管理好activity的生命周期。右图是Android的docs中提供的activity的时间触发图。
四大状态
一般来讲,某一时刻,Activity处在下面四个状态之一:
Active:已由用户启动,正在前台运行。
Paused:已由用户启动,正在运行且可视,但是由于提示或者其他覆盖部分的屏幕。这是用户可以看到activity,但不能与activity进行互动。例如有来电,给出接听或者拒绝的选择。
Stopped:已由用户启动,正在运行,但是由于其他activity而被隐藏,无法向用户直接呈现有效的信息,但是可以通过notification进行通信。
Dead:activity没有启动或者终结,例如为了释放紧缺的内存空间。
状态转变的事件
当状态改变时,Android会提供1个或者多个触发调用方法。我们通过重写这些方法来实现我们的处理。
public class MyActivity extends Activity{
protected void onCreate(Bundle savedInstanceState){….. }protected void onStart(){….. }
protected void onRestart(){….. }protected void onResume(){….. }
protected void onPause(){….. }
protected void onStop(){….. }
protected void onDestroy(){….. }
}
onCreate()和onDestroy()
onCreate(Bundle),在以前我们经常在onCreate()中加载XML的布局文件。在onCreate()中,对UI进行初始化,并完成其他初始化(只需的处理一次,例如绑定某些监听器)。onCreate()在下面三种情况中会被调用:
- Activity首次启动,也就是自系统加电后第一次启动,Bundle参数为null
- 如果Acivity曾运行,并后来被killed掉,在调用时参数是onSaveInstanceState()的Bundle。
- Activity已经运行,但因为不同设备的状态需要不同的资源,例如竖屏改为横屏,acivity将会re-create,而onCreate()会被调用
onDestroy():在activity生命周期的最后,即关闭时被调用,可以是通过finish()由activity主动关闭,也可能是因为系统需要内存而被动关闭。注意如果RAM紧缺的时候,可能onDestroy()不会被调用,但acvitiy仍会被关闭。在onDestroy()中对onCreate()中获得的资源进行释放。
onStart(),onRestart()和onStop()
onStart()一个activity第一次被调用时,将在前台呈现UI时或者被隐藏后重新在前台呈现时调用,即当用户可以看见或者重新看见activity时调用。
onReStart()在一个activity被stop后重启时调用。
onStop()就是在activity的状态变为stopped状态时调用。
onPause()和onResume()
onResume()在activity成为前台程序时调用,也就是用户可和activity互动时调用。当activity初次调用,或者从一个stopped状态中恢复,先是UI可视-onStart(),然后UI可互动-onResume()。当一个pop-up对话框(例如一个来电,将导致acivity进入Paused状态)消除的情况会触发onResume(),因为Paused的状态中UI是可视,只是被覆盖而无效,因此不会有UI可视-onStart()调用,只有UI可互动-onResume()调用。在onResume()中可进行UI的刷新。
任何使得用户不在关注你的Activity,例如其他activity启动,onPause()被调用,在这里我们可以undo在onResume中do的,停止后台进程,释放原来占用的资源(例如摄像头),一旦onPause()被调用后,当acivity被系统killed的时候,不会收到事件提醒,即不会触发onDestory()。
场景例子
我们通过考察activity中调起令一个activity的情况来看看activity的状态变化事件。
场景1:如果我们在一个activity(activity1)中通过intent启动另一个activity(activity2),那么触发的过程是:
activity1-onPause()->activity2-onCreate()->activity2-onStart()->activity2-onResume()->activity1-onStop()
activity1:失去了用户的焦点,无法和用户进行互动,被activity2覆盖,调用了onPause(),然后是activity2的启动调用过程,通常activity2不是覆盖部分,而且完全占据屏幕,由此activity1被隐藏,activity1进入了Stopped状态,调用activity1-onStop()。如果acvity2已对话框的方式,而不是全屏幕,即activity1不会并因此,仍然保留在Paused状态,则不会触发activity1-onStop()。
activity2:对于一个activity的启动顺序为初始化onCreate() -> 用户可视onStart() -> 用户可互动(获得焦点)onResume()
场景2:我们按菜单的返回键,从activity2退出,并恢复为activity1
activity2-onPause() -> activity1-onRestart() -> activity1-onStart() -> activity1-onResume() ->activity2-onStop() -> activity2-onDestory()
activity1:在场景1中进入Stopped状态,重新恢复,进入onRestart()状态,UI可视onStart(),获得焦点用户可互动onResume()
activity2:按返回键,acivity将被注销,根据android给出来的图,依次进行onPause()失去焦点不可互动->onStop()不可视->on Destory()被关闭。
在mars-android的视频教学中通过一个activity的stack,成为task来解释这种依次调起activity的情形。但是在我下载的更新的reference中,在相应的html中已经删除了相关的内容。但在另外的文档中找到Task的描述。当用户从一个activity跳到一个activity,可以是不同的app,Android系统记录activity的线程导航历史,这就是activity stack,也称为back stack。当前屏幕最前面的UI就是stack最上面的一个activity,当这个activity调起一个新的activity时,这个activity-new将加入这个stack,作为stack最上面的元素,当用户按下BACK键时,将最上面也就是当前UI显示的activity-new从stack中拿走,并删除这个activity-new(进入Deaded状态)。这样可以很好地理解Android处理按下BACK键的情况,这些activity是按一定顺序,不可改变(当然如果我们使用finish()可以删除其中某个acitivity,从stack中去除),处理方式是stack的先进后出。
数据保存
Android可能会因为内存的缘故踢走你的activiy,activiy会保存一些状态,利用这我们可以保存一些我们所需的数据。保存数据的方式为onSaveInstanceState(),要注意,由于activity会频繁地执行之,所以一定要保证高效,只将我们的data存放如Bundle。获取数据有两个途径,一是onCreate(Bundle)中的参数携带该data,二是在onRestoreInstanceState()。我们可以选择所需的数据,这个数据甚至可以是一个callback。
Pop-up对话框
在我们之前的学习中都是新的activity完全覆盖原activity,另一种情况是部分覆盖,使原来的activity进入Paused状态,而不是Stopped,如下图所示。
程序代码和普通没有什么不同,关键是AndroidManifest.xml。如下:
<activity android:name=".MyActivity" android:label="@string/myactivity"android:theme="@android:style/Theme.Dialog" />