activity生命周期中方法解析

对于activity的生命周期我觉得是一个简单而又不简单的问题,很多人可能觉得自己已经很精通了!往往事实却不以为然!

要接着讨论下面的问题,先来简单了解一下activity,来看一段原文的说明,如下:

 An activity is a single, focused thing that the user can do.  Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with {@link #setContentView}.

上文说的很清楚:activity是一个专注于用户操作的独立控件,一般情况下我们的activity都是用于与用户交互的,而activity通过创建的一个window来实现与用户的这种关系,在activity中我们通过setContentView来配置这个window所要显示的内容.

关键词:于用户交互, 创建window, setContentView配置显示内容.

首先来看看activity生命周期的流程图:

相信大家对于上面的流程图很了解,下面我来对上面流程图中各个方法解析一下;

(1)首先来看看第一个重要的方法,当然也是第一常用的方法:onCreate

 protected void onCreate(Bundle savedInstanceState)

对于activity有以下几条总结:

  • 在activity的整个生命周期中:onCreate时第一被调用的方法,当然onDestroy是最后一个被调用的方法.
  • onCreate中通常 通过setContentView来配置你的显示内容,通过findViewById来获取你想要后面用到的view
  • onCreate经常用来初始化全局需要的数据,比如listview的显示数据的配置/SharedPreferences保存的数据/savedInstanceState里面保存的数据等.但是,不是所有需要的数据都在这里获取,比如一些耗时的数据获取(从网络上获取大量图片资源等),你可能需要考虑开辟线程来获取,毕竟我们不能阻塞主线程.
  • Bundle savedInstanceState里面保存的值是从什么地方来:当你的activity调用来onSaveInstanceState之后,你的activity被重启用时候.所以savedInstanceState保存的数据就是onSaveInstanceState里面配置的,其目的就是希望能够从上个被kill的activity实例中恢复回来.因为onSaveInstanceState的调用一般是个意外,对于什么样的意外,后面会讲到.
  • 可以在这个方法里面调用finish()来立即结束这个activity,一旦你这样做,会立即调用onDestroy,而不会调用生命周期中的其他方法.

(2)onStart

 protected void onStart()

对于onStart有以下几条总结:

  • 在生命周期中,onStart时紧接着onCreate被调用.之后会调用onResume.另外:当一个activity从新变得可见(后台状态)时候:onRestart调用后,onStart也会被调用.
  • onStart调用后,该activity变得可见(处于可见状态),但是无发和用户交互(无触摸事件),还不处于前台状态.直到onStop调用时候,该activity在不可见.
  • 所以,在对显示的ui变化的检测: 有影响ui显示的的广播接收器的注册检测/一个lastView显示内容变化的检测(setOnEditorActionListener)等都在这里注册,当然记得在onStop取消注册.举一个例子:一个飞行模式切换的界面.切换飞行模式是一个switch的按钮,在来回点击switch的时候,会去设置飞行模式(开启/关闭),同时将这个swith按钮配置为不可用状态,等飞行模式切换成功时候,才会设置这个switch按钮位可以操作状态,这里如何知道飞行模式切换成功呢?办法就是在onStart里面配置一检测飞行模式状态改变的检测器.

(3)onResume

 protected void onResume()

对于onResume有以下几条总结:

  • onResume调用以后,这个activity就成为来(foreground lifetime)前台activity.这个状态一只持续到onPause被调用.所以activity每一次进入前台状态的时候都要调onResume.
  • onResume被调用就标识这个actovity可以与使用者交互(交流).
  • 需要注意的是:这个地方被调用以后并不能确保这个activity对于使用者来说时可见的.因为一些系统级的窗口可能会覆盖在这个activity之上(比如:锁屏界面).要知道当前的activity是否可见可以通过覆盖这个方法onWindowFocusChanged(boolean hasFocus)来获知.
  • onResume中通常可以启动一些需要的动画效果,获知对于一些需要的设备的开启(比如:camera)

(4)onPause

 protected void onPause()

对于onPause有以下几条总结:
  • 当activity从前台变成后台状态时候会立即调用.
  • 当从当前的activity(A_activity)启动另外一个activity(B_activity)时候,当前的activity会立即调用自己的onPause,并且等这个onPause返回后(执行完),activity(B_activity)才会被创建.所以,onPause的执行事件尽量不要太长.
  • onPause里面通常用来保存activity状态的数据,一般来说时一些activity显示状态的一些简单的数据(SharedPreferences)保存.此外还用来停止正在播放的动画.以及释放耗cpu等其他设备资源的操作(暂停一些不需要的线程/释放不需要的设备camera等),其主要目的是使其可以尽快启动下一个activity.
  • onPause之后,onStop一般会被调用,当然偶尔也不会调用onStop.
  • 我们知道,不处于前台状态的activity是可能被kill的.这个时候onSaveInstanceState会被调用,这个地方用来保存数据,以便下次能够恢复这个被调用过的又被意外kill掉的activity. 这里保存的数据和上面的石油差别的:onSaveInstanceState中通常保存的数据相对于application来说时全局的,而不是仅仅使用于这个actovity的.比如content providers等.

(5)onStop

 protected void onStop()

对于onStop有以下几条总结:
  • 当变成后台状态时候,变得不可见时onPause就会被调用.
  • 这个方法是可能永远不被调用的.当memory不够时候,需要kill掉这个activity.

(6)onDestroy

 protected void onDestroy()

对于onDestroy有以下几条总结:
  • 不能试图在onDestroy中保存数据.
  • 一般在onDestroy中释放一些activity自己无法释放的资源,比如你开辟的一些线程/Receiver以及Service的停止等.
  • 在onDestroy中你可以通过isFinishing()来判断是主动通过调用finish来kill这个activity还是意外android因为资源经常等原因kill的.


最后看看activity中的其他几个重要方法:

  • onSaveInstanceState

protected void onSaveInstanceState(Bundle outState)

这个方法的目的是:在一个activity被系统kill之前,来保存这个activity实例的一些状态到这个Bundle里面,以便在这个activity再次启动的时候调用onCreate和onRestoreInstanceState来获取之前的保存的状态.

对于onSaveInstanceState,需要知道以下几点:

(1)onSaveInstanceState(Bundle outState)不是一个activity被kill就一定会被调用的. 我的理解是:如果系统在因为某些原因(比如资源紧张)kill这个activity时候,认为这个activity是会被再次使用的时候就会调用onSaveInstanceState来保存数据,以便下次启用时候可以使用.

这一点理解起来比较复杂,来看看原文给的一个例子:如果activity B的启动在activity A的上面(就是说当activity B中按返回按键时候就回到activity A),可能在系统资源紧张的时候activity A会被系统给kill掉!这个时候,系统就会认为用户此时kill掉的这个activity A是会被调用的,因为只要用户点击返回按键就会调用的activity A.所以这种情况下在kill掉activity A的时候就会回调activity A的onSaveInstanceState.这样就能保证即便是在activity A被kill过,但是返回后仍然显示着原来 的样子.

第二个例子:就是我们经常遇到的横竖屏的切换,我们知道这个时候activity是会首先被kill的,在这种情况onSaveInstanceState时会被调用的,道理很上面一样:系统认为当前kill掉的activity是会再次重复使用的!

(2)onSaveInstanceState和生命周期中的其他方法是不一样的,比如onPause/onStop等! 其主要原因就是onSaveInstanceState不能确定每次kill掉一个activity都被调用.比如上面的activity AB例子:当按返回按键时候,推出activity B时候,在kill这个activity B时候,就不会调用activity B的onSaveInstanceState.因为系统认为这是一个暂时不需要重复使用的activity.这种情况下,activity B的onPause/onStop等生命周期的方法却是会调用的.

(3)onSaveInstanceState调用的时机. 当一个activity被kill掉之前才有可能调用,并且在activity的onStop之后调用,但是不确定是onPause之前/之后调用.下面时原文说明:

   If called, this method will occur before {@link #onStop}.  There are no guarantees about whether it will occur before or after {@link #onPause}.

  • onNewIntent

protected void onNewIntent(Intent intent)

onNewIntent调用时机:

       当通过startActivity方式启动一个activity时,并且启动模式是:"singleTop".或者从新启动一个以及处于statck的顶部的activity时

onNewIntent调用后的intent变化:

      onNewIntent调用后,通过getIntent获取的intent却是以前调用activity的intent,如果要更新intent,你需要在onNewIntent通过调用setIntent来更改为这次启动activity的intent.


  • onWindowFocusChanged

public void onWindowFocusChanged(boolean hasFocus)

     从方法名可以知道这个方法是在当前这个activity的window获得或者取消焦点时候调用的,该方法可以确定当前的activity是否可见.实际上onResume也有类似的作用,不过是有差别的:我们知道activity之所以可以显示内容,是因为其中的window,onResume其实只是针对当前的activity的window,也就是说onResume时activity级的;而onWindowFocusChanged很显然不仅仅是针对activity的window,而是所有的window. 也就是说:就算一个activity处于onResume状态,也有可能其他的非activity的window可能覆盖他而获得焦点.比如popup窗口,dialog窗口,锁屏等. 还需要注意的是:一般情况不用担心onWindowFocusChanged不会被调用到.

  • onAttachedToWindow

public void onAttachedToWindow()

     与view中的onAttachedToWindow类似:当当前activity的window加入到window manager时候,一个window在显示前时需要加入到window manager,所以一个activity的window显示前会调用这个方法onAttachedToWindow.并且在onResume之后调用.

     onAttachedToWindow中通常用来配置当前window的一些属性,比如当需要当前activity获得HOMEKEY事件时候,可以在这个方法里面设置: getWindow().addFlags(FLAG_HOMEKEY_DISPATCHED); 很显然,在调用 onAttachedToWindow的时候这个activity的window以及初始化了.实际上可以做更多的事情,比如在PlatLogoActivity中里面, 其显示的内容都是在onAttachedToWindow里面创建的:包括显示的view的创建和初始化, view动画的初始化等.

  • onDetachedFromWindow

protected void onDetachedFromWindow()

     和上面的onAttachedToWindow相反,只是调用的时机是在onDestroy之后.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章