安卓-生命周期简述

在 Android 中,多数情况下每个程序都是在各自独立的 Linux 进程中运行的。当一个程序或其某些部分被请求时,它的进程就“出生”了;当这个程序没有必要再运行下去且系统需要回收这个进程的内存用于其他程序时,这个 进程就“死亡”了。可以看出,Android 程序的生命周期是由系统控制而非程序自身直接控制。这和我们编写桌面应用程序时的思维有一些不同,一个桌面应用程序的进程也是在其他进程或用户请求时被创 建,但是往往是在程序自身收到关闭请求后执行一个特定的动作(比如从 main 函数中 return)而导致进程结束的。要想做好某种类型的程序或者某种平台下的程序的开发,最关键的就是要弄清楚这种类型的程序或整个平台下的程序的一般工作 模式并熟记在心。在 Android 中,程序的生命周期控制就是属于这个范畴——我的个人理解:)

在 Android 系统中,当某个 activity调用 startActivity(myIntent) 时,系统会在所有已经安装的程序中寻找其 intent filter 和 myIntent 最匹配的一个 activity,启动这个进程,并把这个 intent 通知给这个 activity。这就是一个程序的“生”。比如我们在 Home application 中选择 “Web browser”,系统会根据这个 intent 找到并启动 Web browser 程序,显示 Web browser 的一个 activity 供我们浏览网页(这个启动过程有点类似我们在在个人电脑上双击桌面上的一个图标,启动某个应用程序)。在 Android 中,所有的应用程序“生来就是平等的”,所以不光 Android 的核心程序甚至第三方程序也可以发出一个 intent 来启动另外一个程序中的一个 activity。Android 的这种设计非常有利于“程序部件”的重用。

  一个 Android 程序的进程是何时被系统结束的呢?通俗地说,一个即将被系统关闭的程序是系统在内存不足(low memory)时,根据“重要性层次”选出来的“牺牲品”。一个进程的重要性是根据其中运行的部件和部件的状态决定的。各种进程按照重要性从高到低排列如 下:
  1. 前台进程。这样的进程拥有一个在屏幕上显示并和用户交互的 activity 或者它的一个IntentReciver 正在运行。这样的程序重要性最高,只有在系统内存非常低,万不得已时才会被结束。
  2. 可见进程。在屏幕上显示,但是不在前台的程序。比如一个前台进程以对话框的形式显示在该进程前面。这样的进程也很重要,它们只有在系统没有足够内存运行所有前台进程时,才会被结束。
  3. 服务进程。这样的进程在后台持续运行,比如后台音乐播放、后台数据上传下载等。这样的进程对用户来说一般很有用,所以只有当系统没有足够内存来维持所有的前台和可见进程时,才会被结束。
  4. 后台进程。这样的程序拥有一个用户不可见的 activity。这样的程序在系统内存不足时,按照 LRU 的顺序被结束。
  5. 空进程。这样的进程不包含任何活动的程序部件。系统可能随时关闭这类进程。
 

从某种意义上讲,垃圾收集机制把程序员从“内存管理噩梦”中解放出来,而 Android 的进程生命周期管理机制把用户从“任务管理噩梦”中解放出来。我见过一些 Nokia S60 用户和 Windows Mobile 用户要么因为长期不关闭多余的应用程序而导致系统变慢,要么因为不时查看应用程序列表而影响使用体验。Android 使用 Java 作为应用程序 API,并且结合其独特的生命周期管理机制同时为开发者和使用者提供最大程度的便利。

Activity lifecycle

Activity有三种基本状态:

  1. Active:处于屏幕前景(当前task的栈顶Activity处于Active状态),同一时刻只能有一个Activity处于Active状态;
  2. Paused状态:处于背景画面画面状态,失去了焦点,但依然是活动状态;
  3. stopped:不可见,但依然保持所有的状态和内存信息。

可以调用finish()结束处理Paused或者stopped状态的Activity。

各种状态之间通过下列的函数调用转换:

void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()

Activity的生命周期可以分为三组:

  • The entire lifetime of an activity happens between the first call toonCreate() through to a single final call to onDestroy().
  • The visible lifetime of an activity happens between a call toonStart() until a corresponding call to onStop().

  • The foreground lifetime of an activity happens between a call to onResume() until a corresponding call toonPause().

activity_lifecycle

 

保存Activity状态

To capture that state before the activity is killed, you can implement an onSaveInstanceState() method for the activity. Android calls this method before making the activity vulnerable to being destroyed — that is, before onPause() is called. It passes the method a Bundle object where you can record the dynamic state of the activity as name-value pairs. When the activity is again started, the Bundle is passed both to onCreate() and to a method that's called after onStart(),onRestoreInstanceState(), so that either or both of them can recreate the captured state.

Unlike onPause() and the other methods discussed earlier, onSaveInstanceState() and onRestoreInstanceState()are not lifecycle methods. They are not always called. Because onSaveInstanceState() is not always called, you should use it only to record the transient state of the activity, not to store persistent data. Use onPause() for that purpose instead.

启动另一个Activity的过程

  • The current activity's onPause() method is called.
  • Next, the starting activity's onCreate()onStart(), and onResume() methods are called in sequence.
  • Then, if the starting activity is no longer visible on screen, its onStop() method is called.

    service生命周期

    A service can be used in two ways:

    • It can be started and allowed to run until someone stops it or it stops itself. In this mode, it's started by callingContext.startService()and stopped by calling Context.stopService(). It can stop itself by callingService.stopSelf() or Service.stopSelfResult(). Only onestopService() call is needed to stop the service, no matter how many times startService() was called.
    • It can be operated programmatically using an interface that it defines and exports. Clients establish a connection to the Service object and use that connection to call into the service. The connection is established by callingContext.bindService(), and is closed by callingContext.unbindService(). Multiple clients can bind to the same service. If the service has not already been launched, bindService() can optionally launch it.

    相关的方法:

    void onCreate()
    void onStart(Intent intent)
    void onDestroy()

    The onCreate() and onDestroy() methods are called for all services, whether they're started byContext.startService() or Context.bindService(). However, onStart() is called only for services started bystartService().

    If a service permits others to bind to it, there are additional callback methods for it to implement:

    IBinder onBind(Intent intent)
    boolean onUnbind(Intent intent)
    void onRebind(Intent intent)

    service_lifecycle

     

    Broadcast receiver lifecycle

    只有一个方法:void onReceive(Context curContext, Intent broadcastMsg)

    A process with an active broadcast receiver is protected from being killed. But a process with only inactive components can be killed by the system at any time, when the memory it consumes is needed by other processes.

    This presents a problem when the response to a broadcast message is time consuming and, therefore, something that should be done in a separate thread, away from the main thread where other components of the user interface run. IfonReceive() spawns the thread and then returns, the entire process, including the new thread, is judged to be inactive (unless other application components are active in the process), putting it in jeopardy of being killed. The solution to this problem is for onReceive() to start a service and let the service do the job, so the system knows that there is still active work being done in the process.

    进程的生命周期

    Android根据其重要性在内存不足的时候移去重要性最低的进程。重要性由高到低为:

    1. 前台进程
    2. 可见进程
    3. 服务进程
    4. 后台进程
    5. 空进程

    注意:Because a process running a service is ranked higher than one with background activities, an activity that initiates a long-running operation might do well to start a service for that operation, rather than simply spawn a thread — particularly if the operation will likely outlast the activity. 比如播放MP3的时候就要启动一个service。

    ——————————————————————————————————————————————————————-——————————

    正确地理解活动的生命周期,对于保证应用程序提供一个连贯流畅的用户体验以及合理地管理资源是至关重要的。
           正如前面所解释的,Android应用程序不能控制它们自己的进程的生存期;而Android运行时可以管理每一个应用程序的进程,也就是说,它也可以管理进程内的每个活动。

           除了运行时可以终止一个活动进程并对其进行管理之外,活动的状态也可以帮助你确定其父程序的优先级。而应用程序的优先级又影响着运行时终止进程及其运行活动的可能性。

           1. 活动栈

           每一个活动的状态是由它在活动栈中所处的位置所决定的,活动栈是当前所有正在运行的进程的后进先出的集合。当一个新的活动启动时,当前的前台屏幕就会移动到栈顶。如果用户使用Back(返回)按钮返回到了刚才的活动,或者前台活动被关闭了,那么栈中的下一个活动就会移动到栈顶,变为活动状态。图3-7说明了这个过程。

    效果图:


           2. 活动状态

           随着活动的创建和销毁,它们会按照图3-7所示的那样,从栈中移进移出。在这个过程中,它们也经历了下面4种可能的状态:

           活动状态  当一个活动位于栈顶的时候,它是可见的、被关注的前台活动,这时它可以接收用户输入。Android将会不惜一切代价来保持它处于活动状态,并根据需要来销毁栈下面部分的活动,以保证这个活动拥有它所需要的资源。当另一个活动变为活动状态时,这个活动就将被暂停。

           暂停状态  在某些情况下,活动是可见的,但是没有被关注,此时它就处于暂停状态。当一个透明的或者非全屏的活动位于某个处于活动状态的活动之前时,这个透明的或者非全屏的活动就会达到这个状态。当活动被暂
    停的时候,它仍然会被当作近似于活动状态的状态,但是它不能接收用户的输入事件。在极端情况下,当一个活动变得完全不可见的时候,它就会变为停止状态。

           停止状态  当一个活动不可见的时候,它就处于停止状态。此时,活动仍然会停留在内存中,保存所有的状态和成员信息,然而当系统的其他地方要求使用内存的时候,它们就会成为被清除的首要候选对象。在一个活动停止的时候,保存数据和当前的UI状态是很重要的。一旦一个活动被退出或者关闭,它就会变为非活动状态。

           非活动状态  当一个活动被销毁之后,在它启动之前就处于非活动状态。处于非活动状态的活动已经从活动栈中移除了,因此,在它们可以被显示和使用之前,需要被重新启动。

           状态转化是非确定性的,完全由Android内存管理器处理。Android首先会关闭包含非活动状态活动的应用程序,接着会关闭那些停止的应用程序,只有在极端的情况下,它才会移除那些被暂停的应用程序。

           为了保证连贯流畅的用户体验,这些状态之间的转化应该对用户不可见。活动从暂停、停止或者销毁状态转化为活动状态时,用户应该感觉不到任何区别。所以当一个活动被暂停或者停止时,保存所有的UI状态改变并暂存所有的数据,这些都是很重要的。一旦一个活动变为活动状态,它就应该恢复那些被保存的值。

           3. 监控状态改变

            为了保证活动可以对状态改变做出反应,Android提供了一系列事件处理程序,当活动在完整的、可见的和活动的生存期之间转化时,它们就会被触发。对这些生存期进行了总结。

    效果图:


           下面的框架代码显示了在一个活动中可用的状态变更方法处理程序的存根。每一个存根内的注释都描述了对每一种状态改变事件应该考虑的动作。

    在Activity中,有两个方法用于临时保存、恢复状态信息,这两个方法是:

    • public void onSaveInstanceState(Bundle savedInstanceState);
    • public void onRestoreInstanceState(Bundle savedInstanceState);

    关于这两个方法的描述不是本文要说明的内容,请参考开发者网站!:)

     

    以下几种情况会调用onSaveInstanceState,分别是:

    • 用户按下HOME键;
    • 长按HOME键,选择运行其他的程序;
    • 按下电源按键;
    • 屏幕方向切换(可能);
    • 启动新的Activity等;

    适合临时信息:当要保存持久信息时,不要使用这个保存方法!举个简单的例子,当我们点击Home后,onSaveInstanceState方法会被调用,此时,如果从Settings里面终止程序,那么,回来后发现保存的数据是不存在的。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。


    Java代码:
    import android.app.Activity; 
    import android.os.Bundle;

    public class MyActivity extends Activity { 
    // 在完整生存期开始的时候调用 
    @Override 
    public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    // 初始化一个活动 

    // 在onCreate方法完成之后调用,用来恢复UI状态 
    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState) { 
    super.onRestoreInstanceState(savedInstanceState); 
    //从savedInstanceState中恢复UI状态 
    // 这个bundle也被传递给onCreate 

    // 在一个活动进程的后续的可见生存期之前调用 
    @Override 
    public void onRestart(){ 
    super.onRestart(); 
    // 当知道这个进程中的活动已经可见之后,载入改变 

    // 在可见生存期开始时调用 
    @Override 
    public void onStart(){ 
    super.onStart(); 
    // 既然活动可见,就应用任何要求的UI改变 

    // 在活动状态生存期开始时调用 
    @Override 
    public void onResume(){ 
    super.onResume(); 
    //恢复活动所需要的任何暂停的UI更新、线程或者进程,但是当不活动的时候,就挂起它们 

    // 在活动状态生存期结束的时候调用,用来保存UI状态改变 
    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState) { 
    //把UI状态改变保存到savedInstanceState 
    //如果进程被销毁或者重启,那么这个bundle将被传递给onCreate super.onSaveInstanceState(savedInstanceState); 

    // 在活动状态生存期结束时调用 
    @Override 
    public void onPause(){ 
    //当活动不是前台的活动状态的活动时,挂起不需要更新的UI更新、线程或者CPU密集的进程。 super.onPause(); } 
    // 在可见生存期结束时调用 
    @Override 
    public void onStop(){ 
    // 当进程不可见的时候,挂起不需要的剩下的UI更新、线程或者处理,保存所有的编辑或者 
    // 状态改变,因为这个进程可能会被销毁(从而为其他进程释资源) 
    super.onStop(); 

    // 在完整生存期结束时调用 
    @Override 
    public void onDestroy(){ 
    // 清空所有的资源,包括结束线程、关闭数据库连接等。 
    super.onDestroy(); 
    }

    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值