Android应用程序的生命周期

发布时间:2011年05月13日      浏览次数:652 次
在大多数情况下,每个Android应用程序都运行在自己的Linux进程中。当应用程序的某些代码需要运行时,这个进程就被创建并一直运行下去,直到系统认为该进程不再有用为止。然后系统将回收进程占用的内存以便分配给其它的应用程序。

应用程序的开发人员必须理解不同的应用程序组件(尤其是Activity, Service, 和 BroadcastReceiver)是如何影响应用程序进程生命周期的,这是很重要的一件事情。不正确地使用这些组件可能会导致系统杀死正在执行重要任务的应用程序进程。

一个常见的进程生命周期bug的例子是BroadcastReceiver, 当BroadcastReceiver在BroadcastReceiver.onReceive()方法中接收到一个Intent时,它会启动一个线程,然后返回。一旦它返回,系统将认为BroadcastReceiver不再处于活动状态,因而BroadcastReceiver所在的进程也就不再有用了(除非该进程中还有其它的组件处于活动状态)。因此,系统可能会在任意时刻杀死进程以回收内存。这样做的话,进程中创建(spawned)出的那个线程也将被终止。对这个问题的解决方法是从BroadcastReceiver启动一个服务,让系统知道进程中还有处于活动状态的工作。为了决定在内存不足时让系统杀死哪个进程,Android 根据每个进程中运行的组件以及组件的状态把进程放入一个”重要性分级(importance hierarchy)”中。进程的类型包括(按重要程度排序):

1、前台(foreground)进程,与用户当前正在做的事情密切相关。不同的应用程序组件能够通过不同的方法使它的宿主进程移到前台。当下面任何一个条件满足时,可以考虑将进程移到前台:
(1)进程正在屏幕的最前端运行一个与用户交互的Activity (它的onResume()方法被调用)
(2)进程有一正在运行的BroadcastReceiver (它的BroadcastReceiver.onReceive()方法正在执行)
(3)进程有一个Service,并且在Service的某个回调函数(Service.onCreate(), Service.onStart(), 或 Service.onDestroy())内有正在执行的代码。

2、可见(visible)进程,它有一个可以被用户从屏幕上看到的Activity,但不在前台(它的onPause()方法被调用)。举例来说,如果前台的Activity是一个对话框,以前的Activity隐藏在对话框之后,就可能出现这种进程。这样的进程特别重要,一般不允许被杀死,除非为了保证前台进程的运行不得不这样做。

3、服务(service)进程,有一个已经用startService() 方法启动的Service。虽然这些进程用户无法直接看到,但它们做的事情却是用户所关心的(例如后台MP3回放或后台网络数据的上传下载)。因此,系统将一直运行这些进程除非内存不足以维持所有的前台进程和可见进程。

4、后台(background)进程, 拥有一个当前用户看不到的Activity(它的onStop()方法被调用)。这些进程对用户体验没有直接的影响。如果它们正确执行了Activity生命期(详细信息可参考Activity),系统可以在任意时刻杀死进程来回收内存,并提供给前面三种类型的进程使用。系统中通常有很多个这样的进程在运行,因此要将这些进程保存在LRU 列表中,以确保当内存不足时用户最近看到的进程最后一个被杀掉。

5、空(empty)进程,不包含任何处于活动状态的应用程序组件。保留这种进程的唯一原因是,当下次应用程序的某个组件需要运行时,不需要重新创建进程,这样可以提高启动速度。

系统将以进程中当前处于活动状态组件的重要程度为基础对进程进行分类。请参考Activity, Service 和 BroadcastReceiver文档来获得有关这些组件在进程整个生命期中是如何起作用的详细信息。每个进程类别的文档详细描述了它们是怎样影响应用程序整个生命周期的。进程的优先级可能也会根据该进程与其它进程的依赖关系而增长。例如,如果进程A 通过在进程B中设置Context.BIND_AUTO_CREATE标记或使用ContentProvider被绑定到一个服务(Service),那么进程B在分类时至少要被看成与进程A同等重要。
免责声明:本站相关技术文章信息部分来自网络,目的主要是传播更多信息,如果您认为本站的某些信息侵犯了您的版权,请与我们联系,我们会即时妥善的处理,谢谢合作!