再系统的过一边《Android开发艺术探索》,在此总结,加强印象,记录新的收获
Activity生命周期
1.Q:典型情况下Activity生命周期
A:
a.onCreate():
- 状态:Activity 正在创建
- 任务:做初始化工作,如setContentView界面资源、初始化数据
- 注意:此方法的传参Bundle为该Activity上次被异常情况销毁时保存的状态信息。
b.onStart():
- 状态:Activity 正在启动,这时Activity 可见但不在前台,无法和用户交互。
c.onResume():
- 状态:Activity 获得焦点,此时Activity 可见且在前台,并开始活动。
d.onPause():
- 状态: Activity 正在停止
- 任务:可做 数据存储、停止动画等操作。
- 注意:Activity切换时,旧Activity的onPause会先执行,然后才会启动新的Activity。
e.onStop():
- 状态:Activity 即将停止
- 任务:可做稍微重量级回收工作,如取消网络连接、注销广播接收器等。
- 注意:新Activity是透明主题时,旧Activity都不会走onStop。
f.onDestroy():
- 状态:Activity 即将销毁
- 任务:做回收工作、资源释放。
g.onRestart():
- 状态:Activity 重新启动,Activity由后台切换到前台,由不可见到可见。
总结:
1.OnStart ,OnStop是从Activity是否可见来回调的
OnResume , OnPause是从Activity是否位于前台来回调的
2.旧Activity先OnPause,然后新的Activity启动
A OnPause
B OnCreate
B OnStart
B OnResume
A OnStop
OnPause 和 OnStop都不能执行耗时操作,尤其时OnPause,这也意味着,我们应当尽量再OnStop中操作,从而使得新Activity尽快显示出来并切换到前台;
还有一点要注意,Activity在处于onPause、onStop、onDestroy状态下,系统都可以销毁该Activity所在进程,所以我们在处理一些要保存的数据时,必须在onPause方法中进行,因为onStop和onDestroy方法不一定会被调用。
保存数据在OnPause中,不适合用来保存比较费时的数据,其他工作在onStop中
我们把Activity比作一本书,我们要看书,首先从书架上取出书(onCreate),然后放到桌上(onStart),接着打开书(onResume),这样我们就可以看书并可以在书本上写字了。
如果这时候我们要启动另一个Activity,也就是要看另一本书,首先我们放下手中的笔或者说合上书(onPause),然后从书架上拿下另一本书(书2:onCreate),然后把书本2放到桌上并打开(书2:onStart、onResume)。
如果书本1被书本2完全盖住了,即不可见了,就调用书本1的onStop;而如果书本2较小,没有完全盖住书本1,则不会调用。
我们还可以把书本1放回书架上,即onDestroy。
2.Activity生命周期的切换过程
①启动一个Activity:
- onCreate()-->onStart()-->onResume()
②打开一个新Activity:
- 旧Activity的onPause() -->新Activity的onCreate()-->onStart()-->onResume()-->旧Activity的onStop()
③返回到旧Activity:
- 新Activity的onPause()-->旧Activity的onRestart()-->onStart()-->onResume()-->新Activity的onStop()-->onDestory();
④Activity1上弹出对话框Activity2:
- Activity1的onPause()-->Activity2的onCreate()-->onStart()-->onResume()
⑤关闭屏幕/按Home键:
- Activity2的onPause()-->onStop()-->Activity1的onStop()
⑥点亮屏幕/回到前台:
- Activity2的onRestart()-->onStart()-->Activity1的onRestart()-->onStart()-->Activity2的onResume()
⑦关闭对话框Activity2:
- Activity2的onPause()-->Activity1的onResume()-->Activity2的onStop()-->onDestroy()
⑧销毁Activity1:
- onPause()-->onStop()-->onDestroy()
3.onSaveInstanceState和onRestoreInstanceState
通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。
- onSaveInstanceState的调用时机
当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。
(1)、当用户按下HOME键时。
这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
(2)、长按HOME键,选择运行其他的程序时。
(3)、按下电源按键(关闭屏幕显示)时。
(4)、从activity A中启动一个新的activity时。
(5)、屏幕方向切换时,例如从竖屏切换到横屏时。
onSaveInstanceState()的调用遵循一个重要原则,即当系统存在“未经你许可”时销毁了我们的activity的可能时,则onSaveInstanceState()会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据。
该方法调用在onStop之前,但和onPause没有时序关系。
- onRestoreInstanceState的调用时机
onRestoreInstanceState()被调用的前提是,activity“确实”被系统销毁了
该方法在onStart之后
可通过onRestoreInstanceState(Bundle savedInstanceState)和onCreate((Bundle savedInstanceState)来判断Activity是否被重建,并取出数据进行恢复。但需要注意的是,在onCreate取出数据时一定要先判断savedInstanceState是否为空。另外,谷歌更推荐使用onRestoreInstanceState进行数据恢复。
a.由于资源相关配置发生改变,导致Activity被杀死和重新创建
例如屏幕发生旋转:当竖屏切换到横屏时,会先调用onSaveInstanceState来保存切换时的数据,接着销毁当前的Activity,然后重新创建一个Activity,再调用onRestoreInstanceState恢复数据。
- onSaveInstanceState-->onPause(不定)-->onStop-->
onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume
为了避免由于配置改变导致Activity重建,可在AndroidManifest.xml中对应的Activity中设置android:configChanges="orientation|screenSize"。此时再次旋转屏幕时,该Activity不会被系统杀死和重建,只会调用onConfigurationChanged。因此,当配置程序需要响应配置改变,指定configChanges属性,重写onConfigurationChanged方法即可。
b.由于系统资源不足,导致优先级低的Activity被回收
①Activity优先级排序:
- 前台可见Activity>前台可见不可交互Activity(前台Activity弹出Dialog)>后台Activity(用户按下Home键、切换到其他应用)
②当系统内存不足时,会按照Activity优先级从低到高去杀死目标Activity所在的进程。
③若一个进程没有四大组件在执行,那么这个进程将很快被系统杀死。