为什么要了解Activity的生命周期
了解Activity
的生命周期的根本目的就是为了设计用户体验更加良好的应用。了解Activity
的生命周期和各回调方法的触发时机,我们可以更好的在合适的地方向用户展现数据,保证数据的完整性和程序的良好运行。
下面是官方文档的原话:
Managing the lifecycle of your activities by implementing callback methods is crucial to developing a strong and flexible application. The lifecycle of an activity is directly affected by its association withother activities, its task and back stack.
对于开发一个强大和灵活的应用程序,实现Activity的回调方法来管理Activity的生命周期至关重要。一个Activity的生命周期直接影响与它结合的其他Activitys和它的任务返回堆栈。
Activity生命周期图
通过上图,我们可以看到这些方法定义了Activity整个生命周期。
1、entire lifetime (整个生命周期)
一个
Activity
整个生命周期,存在于onCreate()
方法和onDestroy()
调用之间。你的Activity
应该在onCreate()
方法里执行设置“全局”状态(如定义布局)。并在onDestroy()
方法里释放所有剩余资源。例如,如果你的活动有一个线程在后台运行下载网络数据,它可以在onCreate()
中创建该线程,然后在onDestroy()
中停止线程。
2、visible lifetime(可见生命周期)
一个
Activity
可见生命周期,存在于onStart()
和onStop()
调用之间。在此期间,用户可以看到屏幕上的Activity
并与之交互。当一个其他的Activity
启动,并且这个Activity
完全不可见的时候,onStop()
方法就会被调用。在这两个方法,你可以保持该Activity
需要展示给用户的资源。例如,您可以在onStart()
方法里注册一个BroadcastReceiver
来监控你的UI
的变化,并在onStop()
方法里注销它。在整个生命周期的活动中,系统可能会调用onStart()
和onStop()
多次,因为活动之间交替进行隐藏或显示给用户。
3、 foreground lifetime(前台生命周期)
一个Activity前台生命周期,存在于
onResume()
和onPause()
调用之间。在这段时间里,这个Activity
在其他所有Activity
的前面,拥有用户输入焦点。一个Activity
可以经常在前台状态发生转换 —– 比如,当设备休眠或者弹出了个对话框。因为经常会发生转换,所以在这两个方法之间的代码应该是轻量级的,防止导致其他转换变慢使得用户需要等待。
一个Activity本质上只有三种状态:
Resumed(运行)
、Paused(暂停)
、Stopped(停止)
,因为从Activity
被创建之后,它只可能在这三种状态保持长久的停留,其他的回调方法结束后的状态都只能称之为过渡状态。比如进入到onStart()
方法后,执行完该方法,会立即进入到onResume()
方法。
即使一个
Activity
进入到onPaused
或者Stopped
方法,它仍然是存在的,被保存在任务返回堆栈中。它仍然保持着自身的所有实例和状态,所以根本不用担心它在返回到onResume()
方法时,实例会变为null
,或者控件的事件监听不了。唯一需要考虑的就是,系统在内存不足的情况下,杀死在Paused
或者Stopped
状态下的Activity。
当一个Activity
在Resumed
状态下,它是不会因内存不够而被系统直接杀死(在极端的情况下也有可能被杀死,但是一般不会考虑这种情况)。
只有进入
Paused
或者Stopped
状态才会,而且可能根本就不会去调用onStop()
和onDestory()
方法,所以onPause()
方法是我们最大程度上保证Activity
在销毁之前能够执行到的方法。因此,如果你的某个Activity
需要保存某些数据到数据库,您应该在onPause()
里编写持久化数据的代码。但要注意,你应该选择哪些信息必须保留在onPause()
,因为这个方法任何阻塞程序都会阻止过渡到下一个Activity
,这样给用户体验就感觉十分缓慢。
回调方法应该干些什么?
回调方法的作用,就是通知我们Activity
生命周期的改变,然后我们可以处理这种改变,以便程序不会崩溃或者数据丢失等等,也就是拥有更好的用户体检,那么这么多回调方法里到底应该怎么做呢?
1、onCreate()
最重要是在里面调用setContentView()
,还可以在里面初始化各控件、设置监听、并初始化一些全局的变量。
因为在
Activity
的一次生命周期中,onCreate()
方法只会执行一次。在Paused
和Stopped
状态下恢复或重启的下,这些控件、监听和全局变量也不会丢失。即便是内存不足,被回收了,再次Recreate
的话,又是一次新的生命周期的开始,又会执行onCreate()
方法。
还可以在onCreate()
执行数据操作,比如从Cursor
中检索数据等等,但是如果你每次进入这个Activity
都可能需要更新数据,那么最好放在onStart()
里面。
2、onDestory()
确定某些资源是否没有被释放,做一些最终的清理工作,比如在这个
Activity
的onCreate()
中开启的某个线程,那么就要在onDestory()
中确定它是否结束了,如果没有,就结束它。
3、onStart()和onRestart()、onStop()
Activity
进入到Stopped
状态之后,它极有可能被系统所回收,在某些极端情况下,系统可能是直接杀死应用程序的进程,而不是调用onDestory()
方法,所以我们需要在onStop()
方法中尽可能的释放那些用户暂时不需要使用的资源,防止内存泄露。
尽管onPause()
在onStop()
之前执行,但是onPause()
只适合做一些轻量级的操作,更多的耗时耗资源的操作还是要放在onStop()
里面,比如说对数据保存,需要用到的数据库操作。
因为从
Stopped
状态重启之后,onStart()
和onRestart()
方法都会被执行,所以我们要判断哪些操作分别要放在哪个方法里面 。因为可能在onStop()
方法里面释放了一些资源,那么我们必须要重启他们,这个时候这些重启的操作放在onStart()
方法里面就比较好(因为onCreate()
之后也需要开启这些资源)。那些因为Stopped()
之后引发的需要单独操作的代码,就可以放在onRestart()
里面。
4、onResume()和onPause()
onPause()
和onResume()
中做的操作,其实意义上和onStart()
和onStop()
差不多,只不过是要更轻量级的,因为onPause()
不能阻塞转变到下一个Activity
。
比如:在
onPause()
中停止动画、取消broadcast receivers
。当然相应的需要在onResume()
中已经初始化或重启。
有时候也需要在onPause()
判断用户是调用finish()
结束这个Activity
,还是暂时离开,以便区分处理。这时候可以调用isFinishing()
方法来判断。如果是用户finish()
这个Activity
,那么返回为true
,如果只是暂时离开或者被系统回收的话,就返回false
。
Activity
的生命周期与程序的健壮性有着密不可分的关系。
感谢Kilnn和liuhe688的文章:
http://blog.youkuaiyun.com/lonelyroamer/article/details/8927940
http://blog.youkuaiyun.com/liuhe688/article/details/6733407