1.4 组件生命周期
应用程序组件都有生命周期——由Android实例化以响应Intent对象开始、直到这个实例被销毁。在此期间,组件可以是激活或者非激活状态。 如果是Activity,则还包括对用户的可见或不可见状态。本节讨论Activity、服务以及广播接收器的生命周期,包括它们在生命周期中的可能状 态、在状态转变时调用的通知方法、以及当这些进程被关闭或实例被销毁时,这些状态产生的影响。
1.4.1 Activity生命周期
本质上Activity有三个状态:
- 当它在屏幕前台时(位于当前任务堆栈的顶部),它是激活或运行状态。它就是响应用户操作的Activity。
- 当它失去焦点但仍然对用户可见时,它处于暂停状态。即在它之上有另外一个Activity。这个Activity也许是透明的,或者没有完全覆盖 全屏,所以被暂停的Activity仍对用户可见。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接),但 系统处于极低内存时仍然可以杀死这个Activity。
- 完全被另一个Activity覆盖时则处于停止状态。它仍然保留所有的状态和成员信息。然而对用户是不可见的,所以它的窗口将被隐藏,如果其它地方需要内存,则系统经常会杀死这个Activity。
如果Activity处于暂停或停止状态,系统可以通过要求它结束(调用它的 finish() 方法)或直接杀死它的进程来将它驱出内存。当它再次为用户可见的时候,只能完全重新启动并恢复至以前的状态。
当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()
所有这些方法都被挂接,因此我们可以重载他们以在状态改变时进行适当的处理。所有的Activity都必须实现 onCreate()来执行对象第一次实例化时的初始化。很多Activity会实现onPause()以提交数据变化或准备停止与用户的交互。
所有Activity的生命周期方法实现中都必须先调用其父类的版本。比如说:
protected void onPause() {
super.onPause();
. . .
}
总得来说,这七个方法定义了Activity的完整生命周期。实现这些方法可以帮助我们监视其中的 三个嵌套生命周期循环 :
- Activity 的完整生命周期 自第一次调用onCreate()开始,直至调用onDestroy()为 止。Activity在onCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。例如,如果 Activity有一个线程在后台运行从网络上下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。
- Activity的 可视生命周期 自onStart()调用开始直到相应的onStop()调用结束。在此期 间,用户可以在屏幕上看到Activity,尽管它也许并不是位于前台或者也不与用户进行交互。在这两个方法之间,我们可以保留用来向用户显示这个 Activity所需的资源。例如,当用户不再看见我们显示的内容时,我们可以在onStart()中注册一个BroadcastReceiver来监控 会影响UI的变化,而在onStop()中来注消。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。
- Activity的 前台生命周期 自onResume()调用起,至相应的onPause()调用为止。在此期 间,Activity位于前台最上面并与用户进行交互。Activity会经常在暂停和恢复之间进行状态转换——例如当设备转入休眠状态或者有新的 Activity启动时,将调用onPause() 方法。当Activity获得结果或者接收到新的Intent时会调用onResume() 方法。因此,这两个方法中的代码应当是轻量级的。
下图展示了上述循环过程以及Activity在此过程中历经的状态改变。着色的椭圆是Activity可以经历的主要状态。矩形框表示在Activity状态间发生改变的时候,我们可以实现的方法进行适当的处理。
下表详细描述了这些方法,以及他们在Activity整个生命周期中的位置。
请注意上表中可被杀死一列。它标示了在方法返回后,还没执行Activity的其余代码的任意时间里,系统是否可以杀死包含此Activity的进程。三个方法(onPause()、 onStop()和onDestroy())被标记为“是”。 onPause()是 三个中的第一个,它也是 唯一一个在进程被杀死之前必然会调用的方法──onStop() 和 onDestroy() 有可能不被执行。因此你应该用 onPause() 来将所有持久性数据(比如用户的编辑结果)写入存储之中。
在可被杀死一列中标记为“否”的方法在它们被调用时将保护Activity所在的进程不会被杀死。所以只有在onPause()方法返回后到 onResume() 方法被调用时,一个Activity才处于可被杀死的状态。在onPause()再次被调用并返回之前,它不会被系统杀死。
如后面一节进程和生命周期所述,即使是在这里技术上没有被定义为“可杀死”的Activity仍然有可能被系统杀死──但这仅会发生在实在没有其它方法的极端情况之下。
保存Activity状态
当系统而不是用户自己出于回收内存的考虑,关闭了一个Activity之后。用户会期望当他再次回到那个Activity的时候,它仍保持着上次离开时的样子。
为了获取Activity被杀死前的状态,你应该为Activity实现onSaveInstanceState() 方法。Android在Activity有可能被销毁之前(即onPause() 调用之前)会调用此方法。它会将一个以名称-值对方式记录了Activity动态状态的Bundle 对象传递给该方法。当Activity再次启动时,这个Bundle会传递给onCreate()方法和随着onStart()方法调用的 onRestoreInstanceState(),所以它们两个都可以恢复捕获的状态。
与onPause()或先前讨论的其它方法不同,onSaveInstanceState() 和 onRestoreInstanceState() 并不是生命周期方法。它们并不是总会被调用。比如说,Android会在Activity易于被系统销毁之前调用 onSaveInstanceState(),但用户动作(比如按下了BACK键)造成的销毁则不调用。在这种情况下,用户没打算再次回到这个 Activity,所以没有保存状态的必要。
因为onSaveInstanceState()不是总被调用,所以你应该只用它来为Activity保存一些临时的状态,而不能用来保存持久性数据。而是应该用onPause()来达到这个目的。
协调Activity
当一个Activity启动了另外一个的时候,它们都会经历生命周期变化。一个会暂停乃至停止,而另一个则启动。这种情况下,可能需要协调好这些Activity:
生命周期回调顺序是已经定义好的,尤其是在两个Activity在同一个进程内的情况下:
1. 调用当前Activity的 onPause() 方法。
2. 接着,顺序调用新启动Activity的onCreate()、 onStart()和onResume()方法。
3. 然后,如果启动的Activity不再于屏幕上可见,则调用它的onStop()方法。