对于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有以下几条总结:
(2)onStart
protected void onStart()
对于onStart有以下几条总结:
(3)onResume
protected void onResume()
对于onResume有以下几条总结:
(4)onPause
protected void onPause()
(5)onStop
protected void onStop()
(6)onDestroy
protected void onDestroy()
最后看看activity中的其他几个重要方法:
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}.
protected void onNewIntent(Intent intent)
onNewIntent调用时机:
当通过startActivity方式启动一个activity时,并且启动模式是:"singleTop".或者从新启动一个以及处于statck的顶部的activity时
onNewIntent调用后的intent变化:
onNewIntent调用后,通过getIntent获取的intent却是以前调用activity的intent,如果要更新intent,你需要在onNewIntent通过调用setIntent来更改为这次启动activity的intent.
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不会被调用到.
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动画的初始化等.
protected void onDetachedFromWindow()
和上面的onAttachedToWindow相反,只是调用的时机是在onDestroy之后.