`
wangangie5
  • 浏览: 36265 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

Android平台学习:组件的生命周期

 
阅读更多

  Android平台上的应用组件生命周期,以下是我从开发者向导翻译过来的,翻译的不是太好,路过的朋友海涵哈~~
  Activity生命周期
  Activity基本有三个状态
  1、 当它在屏幕最前面时处于活跃或者运行状态(处在当前任务栈的顶部),这个activity获得了用户动作的焦点。
  2、 当它失去焦点但仍然对用户可见时则处于暂停状态。也就是说,另一个activity在它的上面但没有覆盖整个屏幕。一个暂停状态的activity完全是存活着的,它维持着它的状态和成员信息,但是系统在资源极其缺乏时可以终止运行该activity。
  3、 当它完全被另一个activity遮挡不可见时,就处于停止状态。它仍然维持着它的状态和成员信息,然而,它不再对用户可见所以它的窗口是隐藏的,并且通常情况下该activity所占用的内存要用于其它地方时系统会终止它的运行。
  如果一个activity处于暂停或停止状态,系统可以调用finish()方法结束该activity,或者结束它的进程来终止它。当它再一次显示给用户时,它必须重新启动并且恢复它之前的状态。
  activity在各个状态的转换是通过调用以下方法实现的: void onCreate(Bundle savedInstanceState)
  void onStart()
  void onRestart()
  void onResume()
  void onPause()
  void onStop()
  void onDestroy() 这七个方法定义了activity的整个生命周期,通过实现它们,你可以掌控以下三个嵌套循环:
  1、 第一次调用onCreate()到最终调用onDestroy()表示一个activity的整个生命期。一个activity在onCreate()方法中会初始化设置所有全局状态,并在onDestroy()中释放所有占有的资源。比如,如果有一个线程在后台从网络下载数据,这个线程可以在onCreate()中创建,然后在onDestroy()中被停止。
  2、 从调用onStart()到调用onStop()之间是activity的可见性生命期。在这段时期,虽然它可能不在最前面,但用户可以在屏幕上看见该activity。在这两个方法之间,你可以维持需要的资源并将activity显示给用户。比如,你可以在onStart()方法中注册一个BroadcastReceiver对象监听你UI上发生的事件,并且当用户不再需要看你所显示的东西时可以在onStop()方法中取消注册。当这个activity在对用户可见和隐藏之间进行交替时,这两个方法可以被多次调用。
  3、 从调用onResume()到调用onPause()是activity的前景生命期。在这段时期,activity在所有其他activity的前面并且可与用户进行交互。一个activity可能在重新恢复和暂停状态之间频繁转换,比如,当设备休眠或者一个新的activity启动时onPause()方法会被调用,当一个activity result或者一个新的intent对象被接收到时onResume()会被调用。因此,在这两个方法中的代码应该是轻量级的。
  下面这幅图显示了这些循环以及在各个状态之间转换的路径,有颜色的图形是activity可以处于的状态,矩形图代表了当activity在各状态之间转换时你可以执行操作的回调方法。
  
  下面是对生命期回调方法的介绍:  Method Description Killable? Next onCreate() 当activity第一次被创建时调用该方法,在这里你应该做所有全局性的静态的创建工作,比如创建视图,绑定数据等等,这个方法传递一个Bundle对象,如果activity状态曾被捕获过,该对象会包含这些状态数据 NO onStart() onRestart() Activity已经停止后可调用该方法,用以重新启动它,后面总是会调用onStart() NO onStart() onStart() 当activity刚好对用户可见之前系统会调用该方法。如果它将处于最前面,则后面会调用  onResume()方法,如果它将被隐藏,则会调用onStop()方法 NO onResume().onStop() onResume() Activity刚开始与用户交互之前调用该方法,这个时候该activity处于栈的顶部,用户可以与之交互 NO onPause() onPause() 当系统将要恢复另一个activity时调用该方法,这个方法典型的作用是提交没有保存的持久化数据,停止动画和其他可能比较耗费CPU的事情等等,因为下一个activity在这个方法返回之前不会恢复,所以onPause()方法应该很快的运行。如果这个activity重新回到屏幕最前面,会调用onResume(),如果它将对用户不可见,则会调用onStop() YES onResume(),onStop() onStop() Activity不再对用户可见时调用该方法,这发生在它可能被系统回收,或者其他activity被恢复并且覆盖了当前的activity时。当这个activity要恢复与用户的交互,则后面会调用onRestart(),如果会被系统回收,则会调用onDestroy() YES onRestart(),onDestroy() onDestroy() 在activity被回收之前调用该方法,这是它能收到的最终调用,当activity完成时,或者系统为节省空间要回收该实例时就可以调用它,你可以通过isFinished()方法来区分这两种状况 YES   注意上表中Killable一栏,它标识系统是否可以在相应方法返回后、没有执行其他activity代码之前终止运行持有该activity的进程,onPause()、 onStop()、 onDestroy()三个方法被标记为YES,onPause()是唯一一个在进程被终止之前可以保证调用的方法,其他两个方法不行。因此,你应该在onPause()方法中进行数据持久化操作。
  标记为NO的栏表示当对应方法被调用时系统会保护持有该activity的进程免被终止,这时activity处于可终止状态,比如,从onPause()返回到调用onResume(),如果没有再次调用onPause()并返回,该activity将不可终止。
  保存activity状态
  当系统而不是用户要终止activity以节省内存时,用户可能需要重新显示该activity并回到它之前的状态。
  在activity被终止之前要捕获它的状态,你可以实现Activity的onSaveInstanceState()方法,Android会在activity被标记为可终止之前调用该方法,也就是在调用onPause()方法之前。系统会传递一个Bundle对象给这个方法,该对象以键值对的形式记录了activity的静态数据。当activity被再次运行时,Bundle会传递给onCreate()和之后的onStart(),onRestoreInstanceState()。
  不像onPause()和其他之前提到的方法,onSaveInstanceState() 和 onRestoreInstanceState()不是生命周期方法,并不总是会被调用。比如,activity变为可终止之前系统会调用onSaveInstanceState(),但当该实例被用户动作终止时可能就不会调用(比如按下了BACK键),那样的话,用户可能并不期望返回到该activity,也就没有理由保存它的状态。因为onSaveInstanceState()不总是会被调用,你使用它应该仅仅是保存activity的临时状态,而不是持久化数据,建议用onPause()方法做那些工作。
  协调activity
  当一个activity启动另一个activity,它们都要经历生命期的转变。当一个activity启动时,另一个暂停并可以停止,有时,你需要协调这些activity的运行。
  生命周期回调的次序被很好的定义了,特别是当两个activity在同一个进程当中时,如下:
  1、 当前activity的onPause()被调用
  2、 下一步,被启动的activity的onCreate(),onStart(),onResume()被依次调用
  3、 最后,如果被启动的activity在屏幕上不再可见,它的onStop()方法被调用
  Service生命周期
  一个服务可以以两种方式使用
  1、 它可以被一直运行直到系统停止它或者它自己停止自己。这种模式下,调用Context.startService()开始服务并终止于调用Context.stopService(),它也可以通过调用Service.stopSelf() 或者 Service.stopSelfResult()终止自己的运行,不管startService()被调用多少次,stopService()只需要调用一次就可以停止服务。
  2、 使用一个接口可以通过编程操作并使用服务。客户建立一个到某个服务的连接,并使用这个连接请求服务。连接是通过调用Context.bindService()建立的,调用Context.unbindService().可以关闭连接,多个客户可以绑定在同一个服务上,如果服务还没有启动,bindService()方法可以启动这个服务。
  这两种模式不是完全分离的,你可以绑定到一个用startService()方法启动的服务上。比如,有一个代表播放音乐信息的Intent对象被传递给startService(),这样启动了一个背景音乐服务。仅仅过了一会儿,用户又想获得当前播放歌曲的信息,就可以让某个activity调用bindService()以便建立到这个服务的连接。像这样的话,stopService()方法在最后的绑定未被关闭前是无法停止服务的。
  像activity一样,一个service有一些生命周期方法,你可以实现它们以便掌控service状态的变化。但这里只有三个方法,并且它是public而不是protected: void onCreate()
  void onStart(Intent intent)
  void onDestroy() 通过实现这些方法,你能掌控service声明周期中的两个嵌套循环:
  1、 调用onCreate()到调用onDestroy()表示service的整个生命期。跟activity一样,调用onCreate()方法时将进行初始化工作,在onDestroy()里则是释放持有的资源,比如,一个音乐播放服务会在onCreate()里创建音乐播放到哪里的一个线程,在onDestroy()里停止该线程
  2、 Service的活动期开始于调用onStart()。
  不管是用Context.startService()还是Context.bindService()启动,所有服务都会调用onCreate(),onDestroy()方法,但onStart()方法只有在用startService()启动的服务才会调用。
  如果一个服务允许其他组件绑定该服务,那么可以实现以下回调方法: IBinder onBind(Intent intent)
  boolean onUnbind(Intent intent)
  void onRebind(Intent intent) onBind()回调方法会接收传递给bindService方法的intent对象,onUnbind()接收传递给unbindService()的intent对象,如果服务不允许绑定,onBind()方法将返回一个客户与服务进行交互的通信渠道。如果一个新的客户连接到该服务,onUnbind()方法能够请求调用onRebind()方法。
  下图展示了服务的各个回调方法。尽管这里将通过startService()创建的service与通过bindService()创建的service分离开了,但只需要记住的是,不管哪种方式创建的,任何服务都能够允许客户绑定它,因此,任何服务都可以接收onBind()和onUnbind()方法的调用。
  
  Broadcast receiver生命周期
  一个Broadcast receiver只有一个回调方法: void onReceive(Context curContext, Intent broadcastMsg) 当Broadcast receiver接收到一条广播信息,android会调用它的onReceive()方法,并传递给它一个包含广播信息的intent对象。当Broadcast receiver在执行这个方法时可以认为它是活动的,onReceive()方法返回时,它便终止了。 一个包含活动Broadcast receiver的进程会被系统保护以避免被终止。但是如果进程不包含任何活动组件,那么当它占用的内存要用于其它进程时,系统任何时候都可以终止运行该进程。
  当应答一条广播信息十分耗时,而另一个线程必须执行某个任务时会出现一个问题。试想一下,如果onReceive()方法产生一个线程然后返回,那么整个进程,包括新的线程会被认为是不活动的(除非在进程中还有其它活动的组件),该进程就有被系统终止运行的危险。解决这个问题的办法就是在onReceive()方法中启动一个服务,让这个服务做那样的工作,这样系统就会知道进程中有活动的组件而不会停止进程。
  进程和生命周期
  Android系统会维持一个应用进程尽可能长的时间,但最终当内存消耗太多时就需要移除这些进程。为了决定哪个进程应该继续维持,哪个进程会被终止运行,android将每个进程置于一个重要的层次体系中,这个体系以运行在上面的各个组件以及这些组件的状态为基础。其中最不重要的进程将首先被终止运行,其次是下一个不重要的,依次类推。这个体系中有五个级别,下面以重要的次序显示了它们的列表:
  1. 前端进程:指在处理用户当前正在做的事情的进程。当有下列情形之一时该进程就属于前端进程
  l 在运行一个正与用户交互的activity
  l 它持有一个绑定到正与用户交互的activity的service
  l 它持有一个正在执行生命周期回调方法之一(onCreate(),onStart(),onDestroy())的service
  l 它持有一个正在执行onReceive()方法的BroadcastReceiver对象
  在给定的时间只有很少的前端进程存在,它们仅仅在内存所剩无多不能继续运行时才会被终止运行。一般说来,那个时候设备处于内存分页状态,所以才终止这些前端进程以保持用户界面是可响应的。
  2.可见进程:是没有任何前端组件,但仍然可以影响用户所看见的内容的进程。当一
  个进程具有以下情况之一便是可见进程:
  l 它持有一个不在前端的activity,但这个activity对用户仍然可见。
  l 它持有一个绑定到可见activity上的service
  一个可见进程是非常重要的,它不会被终止运行,除非有必要为了保证前端进程运行
  3.服务进程:是一个正在运行startService()方法启动的服务的进程。尽管服务进程没有与用户看到的东西直接关联,它们只做些用户喜欢的事情(比如在后台播放MP3或者从网络下载数据),所以系统会维持它们运行,除非系统没有更多的内存给前端组件和前端进程运行时才会终止服务。
  4.后台进程:是一个持有对当前用户不可见的activity的进程。这些进程不会直接影响到用户,为了为前端进程、可见进程、服务进程回收内存,在任何时候都可以被终止运行。通常会有很多后台进程在运行,所以它们被保存在一个LRU列表中,用以确保包含用户最近看见过的activity的进程是最后被终止运行的,如果一个activity正确的实现了它的生命周期方法,并且捕获了当前的状态,对用户体验来说终止它的进程会有很坏的影响。
  5.空进程:不持有任何活动的应用组件的进程。系统维持这样的一个进程的唯一原因是,作为缓存需要加速启动时间,当下次某个组件需要在那个进程运行时便能实现这一点。为了在进程缓存和基础内核缓存之间平衡系统资源,系统通常会终止这些进程的运行。
  Android指定一个进程的重要级别,是基于在进程中当前活动组件的重要性。比如,一个进程持有一个服务和一个可见activity,这个进程将被指定为可见进程,而不是服务进程。
  另外,如果其他进程依靠这个进程,该进程的级别可以被提升。一个服务于其他进程的进程,它的级别总是会比它服务的进程高,比如,在进程A中的content provider服务于进程B中的客户,或者,进程A中的服务被绑定到进程B中的组件,进程A将至少与进程B具有同样的重要性。
  因为运行服务的进程比运行后台activity的进程重要性更高,为一个需要运行很长时间的操作启动一个服务要比简单的启动一个线程更好,特别是这个操作比activity的生命期还长的时候,这样的一个例子就是后台播放音乐。不管这个activity会发生什么,使用服务保证了这个操作至少拥有服务进程的优先级别。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics