Activity生命周期
# 1. Activity的四种状态
Running(运行)状态:可见也可操作。一个新的Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
Paused(暂停)状态:可见但不可操作。当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。
Stopped(停止)状态:不可见,但对象存在。当Activity不可见时,Activity处于Stopped状态。当Activity处于此状态时,一定要保存当前数据和当前的UI状态(系统会为当前Activity保存相应的状态和成员变量);但这并不是完全可靠的,内存不足时,处于停止状态的Activity可能被系统回收
Killed(死亡)状态:对象不存在。Activity被杀掉以后或者被启动以前,处于Killed状态。这是Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。
4种状态中,Running状态和Paused状态是可见的,Stopped状态和Killed状态时不可见的。
# 2. Activity生命周期方法
# onCreat()
当Activity第一次启动时调用,完成初始化操作(如加载布局,绑定事件),在 Activity 的整个生命周期中只应发生一次
# onRestart()
当Activity调用onStop()之后重新被用户可见时调用
# onStart()
在Activity不可见时调用。当onCreat()之后调用,或onResert()后调用。onStart()
调用使 Activity 对用户可见,因为应用会为 Activity 进入前台并支持互动做准备
onStart()
方法会非常快速地完成,并且与“已创建”状态一样,Activity 不会一直处于“已开始”状态。一旦此回调结束,Activity 便会进入“已恢复”状态,系统将调用 onResume()
方法。
# onResume()
Activity准备好和用户进行交互,此时当前Activity一定位于栈顶并且处于运行状态。这是应用与用户互动的状态。应用会一直保持这种状态,直到某些事件发生,让焦点远离应用。
当onStart()之后调用,或者onPause()之后重新被置入前台时调用
# onPause()
当Activity被置于后台是调用。这个方法准备在系统中去启动 或者 恢复 另外一个Activity时调用。通常在此方法中释放资源及保存关键数据。但是这方法执行要快,不然会影响新的栈顶的Activity的使用
系统将此方法视为用户将要离开您的 Activity 的第一个标志(尽管这并不总是意味着 Activity 会被销毁);此方法表示 Activity 不再位于前台(尽管在用户处于多窗口模式时 Activity 仍然可见)。使用 onPause()
(opens new window) 方法暂停或调整当 Activity
(opens new window) 处于“已暂停”状态时不应继续(或应有节制地继续)的操作,以及您希望很快恢复的操作。Activity 进入此状态的原因有很多。例如:
- 如 onResume() (opens new window) 部分所述,某个事件会中断应用执行。这是最常见的情况。
- 在 Android 7.0(API 级别 24)或更高版本中,有多个应用在多窗口模式下运行。无论何时,都只有一个应用(窗口)可以拥有焦点,因此系统会暂停所有其他应用。
- 有新的半透明 Activity(例如对话框)处于开启状态。只要 Activity 仍然部分可见但并未处于焦点之中,它便会一直暂停。
# onStop()
当Activity不再被用户可见时调用。
在 onStop()
方法中,应用应释放或调整在应用对用户不可见时的无用资源。例如,应用可以暂停动画效果,或从精确位置更新切换到粗略位置更新。
和onPause()的区别在于:如果启动的Activity是对话框,那么此时onStop()并不会执行
# onDestroy
销毁 Ativity 之前,系统会先调用 onDestroy()
(opens new window)。系统调用此回调的原因如下:
- Activity 即将结束(由于用户彻底关闭 Activity 或由于系统为 Activity 调用
finish()
(opens new window)),或者 - 由于配置变更(例如设备旋转或多窗口模式),系统暂时销毁 Activity
以上7个方法中除了onRestart()
方法,其他都是两两相对的,从而又可以将活动分为3种生存期。
- 完整生存期 。活动在
onCreate()
方法和onDestroy()
方法之间所经历的,就是完整生存期。一般情况下,一个活动会在onCreate()
方法中完成各种初始化操作,而在onDestroy()
方法中完成释放内存的操作。 - 可见生存期 。活动在
onStart()
方法和onStop()
方法之间所经历的,就是可见生存期。在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两个方法,合理地管理那些对用户可见的资源。比如在onStart()
方法中对资源进行加载,而在onStop()
方法中对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。 - 前台生存期 。活动在
onResume()
方法和onPause()
方法之间所经历的就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,我们平时看到和接触最多的也就是这个状态下的活动。
# Activity的状态结合方法
运行态-Running
- Activity处于前台,被用户可见,且可控
- Activity从创建到运行状态会经历:
onCreate() => onStart() => onResume()
暂停态-Paused
- Activity被置于后台,可见但不可控
- Activity调用
onPause()
后进入该状态,如恢复运行,会调用onResume()
停止态-Stopped
- Activity被置于后台,不可见,亦不可控
- Activity调用
onStop()
后进入该状态,如恢复运行,调用onRestart() => onStart() => onResume()
终止态-Destroyed
- Activity被系统终止,资源进行回收
- Activity调用
onDestroy()
后进入该状态,如回复运行,需要新创建
当执行完onResume()
方法之后,当前Activity才真正的全部显示完成
# onStart()和onResume()的区别
onStart()是activity界面被显示出来的时候执行的,用户可见,包括有一个activity在他上面,但没有将它完全覆盖,用户可以看到部分activity但不能与它交互
onResume()是当该activity与用户能进行交互时被执行,用户可以获得activity的焦点,能够与用户交互。
onStart()通常就是onStop()(也就是用户按下了home键,activity变为后台后),之后用户再切换回这个activity就会调用onRestart()而后调用onStart()
onResume()是onPause()(通常是当前的acitivty被暂停了,比如被另一个透明或者Dialog样式的Activity覆盖了),之后dialog取消,activity回到可交互状态,调用onResume()。
# 3. 生命周期测试
# 测试方法的流程
1. App刚启动,来到MainActivity
对照流程图,分别执行onCreate() => onStart() => onResume()
,MainActivity获得焦点
2. 点击SecondActivity按钮,激活第二个Activity
此时第一个Activity处于Paused暂停不可见,被SecondActivity覆盖
SecondActivity分别执行onCreate() => onStart() => onResume()
,获得焦点
在SecondActivity获得焦点之后,MainActivity进入Stop(不可见,但对象存在)
3. 点击激活Main按钮,激活第一个MainActivity
同理,此时SecondActivity被MainActivity覆盖,和上述步骤二一致
类比看书,当你在看完当前第二页时,翻页会将之前的一页 “遮挡”
在往回翻时,其又会被显示出来
4. 若不点击 激活Main,而是点击 <返回键> 回到MainActivity
区别于激活,此时MainActivity并不是新创建onCreate()
;因为其已存在回退栈栈中,点击 <返回键>
使SecondActivity退出Back-Stack,此时MainActivity位于前台栈顶,需要重新启动onRestart()
由于SecondActivity退出Back-Stack,所以执行完onStop()
后,退出栈销毁,即执行onDestroy()
5. 点击SmallAtivity按钮,激活第一个SmallActivity 部分遮挡MianActivity
SmallActivity经历相同的三个过程,但是MainActivity 并没有被onStop(),虽然被置于SmallActivity之下,但是MainActivity仍然可见
点击 <返回键> 回到MainActivity,MainActivity只需要onResume()
获得焦点,并不需要重新启动onRestart()
# 测试各个状态的切换
三个途径都可来到onResume()
界面从“死亡”-->“运行” [启动应用]
创建对象-->onCreat()-->onStart()-->onResume()
界面从“运行”-->“死亡” [点返回键]
onPause()-->onStop()-->onDestory()
界面从“运行”-->“停止” [点Home键]
onPause()-->onStop()
界面从“停止”-->“运行” [点完Home键之后,长按Home键回到应用]
onRestart()-->onStart()-->onResume()
界面从“运行”-->“暂停” [当前MainActivity跳转到另一个SecondActivity]
onPause()
界面从“暂停”-->“运行” [SecondActivity返回到MainActivity]
onResume()
# 4. 生命周期注意点
当前Activity为A,此时用户打开ActivityB后,那么A的onPause() 和 B的onResume()哪个方法先执行?
答:先 A的onPause()
,再B的onResume()
Activity的启动过程:由ActivityManagerService(AMS)对栈内的Activity状态进行同步管理 & 规定:新Activity启动前,栈顶的Activity必须先onPause(),才能启动新的Activity(执行onResume())
注:为了让新的Activity尽快切换到前台,在 onPause()尽量不要做耗时 / 重量级操作
# 5. 执行流程小结
当Activity第一次被启动:
onCreate() => onStart() => onResume()
当Activity被遮挡:
onPause() => onStop()
当按 <返回键> 时:
onPause() => onStop() => onDestroy()
当Activity被遮挡后,按 <返回键> 再次显示:
onPause() => onStop() => onDestroy()