1、生命周期的意义
Android对Activity的管理使用的是栈的方式。换句话说,某一时刻只有一个Activity处在栈顶,当这个Activity被销毁后,下面的Activity才有可能浮到栈顶;或者有新的Activity被创建出来,旧的Activity就被压栈下去。
Activity一般有四种状态:
(1)当Activity位于栈顶时,此时正好处于屏幕最前方,此时处于运行状态;
(2)当Activity失去了焦点但仍然对用于可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕),此时处于暂停状态;
(3)当Activity被其他Activity完全遮挡,此时此Activity对用户不可见,此时处于停止状态;
(4)当Activity由于人为或系统原因(如低内存等)被销毁,此时处于销毁状态;
2、生命周期流程
(1)onCreate()-不可见状态
当Activity第一次被加载时执行。新启动一个程序时,其主窗体的onCreate事件会被执行。
一般在创建Activity时需要重写该方法做一些初始化的操作,如通过setContentView设置界面布局的资源,初始化所需要的组件信息等。
(2)onStart()-可见状态
onCreate事件之后执行;或者当前窗体被交换到后台,在用户重新查看窗体前已经过去一段时间,窗体执行了onStop事件,但所在进程以及窗体并未被销毁,用户再次查看窗体时会执行onRestart事件,跳过onCreate,直接执行onStart事件。
此时状态可以理解为Activity已显示,但用户还无法进行交互。
(3)onResume() -可见状态
onStart之后执行;或者当前窗体被交换到后台,在用户重新查看窗体时,窗体未被销毁且没有执行onStop事件,则会跳过onCreate和onStart事件,直接执行onResume。
此时状态可以理解为可以和用户进行交互。
通常情况下可以在该状态中初始化一些资源,如打开相机或开启动画。
(4)onPause() -可见状态
Activity被暂停时调用,该方法用于保存活动状态,也是保护现场。
此方法回调时,Activity正在停止(Paused形态),通常接下来 onStop() 会被回调 。但通过流程图可见,另一种情况是onPause() 执行后直接执行了onResume方法,这可能是用户点击Home键,让程序退回到主界面,程序在后台运行时又迅速地再回到到当前的Activity,此时onResume方法就会被回调。
通常情况下可以在onPause方法中做一些数据存储、动画停止、资源回收等操作。
另外,onPause方法执行完成后,新Activity的onResume方法才会被执行。所以onPause不能太耗时,因为这可能会影响到新的Activity的显示。
(5)onStop() -不可见状态
onPause之后执行,如果一段时间内用户还没有重新查看该窗体,则该窗体的onStop将会被执行;或者用户直接按了Back键,将该窗体从当前Task中移除,也会执行onStop事件。
当前状态Activity仅在后台运行。
通常情况下onStop可以做一些资源释放的操作,不能太耗时。
(6) onRestart()-可见状态
重新启动Activity时被调用。该活动仍在栈中。
调用这个方法一般发生在用户打开了一个新的Activity时,之前的Activity就会被onStop,接着又回到之前Activity页面时,之前的Activity的 onRestart方法就会被回调。
(7)onDestroy() -不可见状态
Activity被完全从系统内存中移除时调用。
该方法被调用可能是因为有人直接调用onFinish();或者系统决定停止该活动以释放资源,在窗体onStop事件之后,如果没有再次查看该窗体,Activity则被销毁。
通常情况下可以在此方法中做一些回收工作和最终的资源释放。
3、问题思考
转自:艾阳博主
1、如果所有的初始化都在onCreate()中实现,会有什么问题?
首先,Activity的onCreate()被调用时,Activity还不可见,如果要做一些动画,既然视图还不存在,在onCreate中来启动动画,明显有问题;
其次,AActivity 切换到 BActivity,再切换到 AActivity,由于实例已经存在,所以onCreate不会再被调用,那问题就在于AActivity从后台切换至前台时,有可能需要一些初始化,就没法被调用到了。
2、如果所有的初始化都在onStart()中实现,会有什么问题?
首先,虽然 在onStart()中用 setContentView()、findViewById() 功能也是正常的,但是onCreate()注释中,明确建议 setContentView()、findViewById() 要在 onCreate() 中被调用。
其次, onResume()的注释中都明确地说了这不是 Activity 对用户是可见的最好的指示器,如果在 onStart() 中做全部初始化,很有可能初始化还没完成影响到用户的交互体验。
3、如果所有资源回收都在onStop()中实现,会有什么问题?
首先,在 onResume() 的注释中,建议是在onResume()中打开独占设备(比如相机),与onResume()对应的是onPause(),关闭相机的操作也应该在此方法中被调用;否则,考虑一下如下场景:如果AActivity打开了相机,我们点击某按钮要跳转到BActivity中,BActivity也想打开相机;假设AActivity的onPause() 在 BActivity启动后再被调用,那BActivity根本就无法再正常启动相机。
在onPause() 的注释中明确表示,应该在这个方法中执行停止动画等比较耗CPU的操作,如果不先执行这些操作,就先启动新应用,然后再来执行此操作,确实是不合逻辑;其次,onStop() 的注释中也明确地写了,在内存不足而导致系统自动回收进程情况下,onStop() 可能都不会被执行。
4、Activity间跳转时,为什么AActivity的onPause()被调用后,BActivity的初始化流程(onCreate() -> onStart() -> onResume()),然后AActivity的onStop()被调用?
从AActivity切换到BActivity的日志如下:
当用户点击打开新的Activity,肯定是想尽快进入新的视图进行操作。而且上面的问题已经解释了,在onResume()一般会打开独占设备,开启动画等,当需要从AActivity切换到BActivity时,先执行AActivity中的onPause()进行关闭独占设备,关闭动画等,以防止BActivity也需要使用这些资源,因为AActivity的资源回收,也有利于BActivity运行的流畅。
当AActivity中比较消耗资源的部分在onPause()中关闭后,再执行BActivity的初始化,显示视图与用户交互。然后,系统在后台默默执行AActivity的onStop()操作,去回收AActivity占用的其余资源。即使onStop()中会有些比较耗时的操作,也没有关系,这是在后台执行也不会影响到用户的体验。(设计的非常好!good!!!)