我要做 Android 第二弹
大家好,这里是我要做 Android 的第二弹,说实话,大四了在学校上课都没什么心情了。真的是有些焦虑了,要不是最近在跟着老师做项目,我觉得我就要进入疯狂找工作模式了。我一直想从事 Android 开发工作,这个目标在大二的时候就决定了。我愿一往无前。不过看了面试题目我决定还是先复(预)习吧。。。
话不多说,开干:
今天我们说 Activity 的 onSaveInstanceState() 和 onRestoreInstanceState() 方法。我在我的上一篇文章中已经详细的介绍了有关 Activity 的生命周期和方法,如果想了解的可以去看看这篇文章:https://www.jianshu.com/p/e246d20f5dd9。所以我们可以明确这两个方法不是生命周期的方法,这是什么意思。
其实在activity的一个生命周期中,onSaveInstanceState() 你不一定能遇得到。
正如官网对该方法的解释所说:“This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. ” 在“可能被系统杀死”之前调用。说的很准确啊,先明白一点:如果一个 activityA 不可能在后台被系统主动kill掉,那么就不会调用该方法
那么回过头,什么时候activity“可能被系统杀死”呢?官网也是有明确说明的:
总结说就是:
onResume() 不会被杀。前台应用,系统是不会主动 kill 的。(废话,不能见谁都 kill 吧是吧,你以为你是社会我龙哥吗。。。)
onPause() HONEYCOMB(android3.0)之前,可能被杀;3.0之后不会被杀。
onStop() 可能被杀。(俗话说见面三分情,我都看不见你了那就管不了这么多了是吧)
明确activity可能在生命周期中被杀的方法之后,根据上边说明便可知:
android3.0之前:onResume() -- [optional] onSaveInstanceState() -- onPause(),即调用onPause()之前,可能调用 onSaveInstanceState()
android3.0之后:onResume() -- onPause() -- [optional] onSaveInstanceState() -- onStop(), 即调用onStop()之前,可能调用 onSaveInstanceState()
如上边特意提到一样,这里仍要注意“可能”,如果一个 activityA 不可能在后台被系统主动 kill 掉,那么就不会调用该方法。
比如以下逻辑:
activityA.startActivity(activityB)
activityA.finish()
A启动了B,但是A自己把自己 finish 了,也就是说系统不可能主动 kill activityA 了,因此虽然 A 的 onPause()、onStop() 被调用,但 onSaveInstanceState() 方法也是不会调用到的。
那么同理,默认情况下在一个activity中,返回退出也是不会调用 onSaveInstanceState() 的。(系统表示这个锅我不背,都是用户的错,谁知道用户会这样操作是吧。。。)
所以总结下大致的常见的几种情况:
1、当用户按下HOME键时。
这是显而易见的,系统不知道你按下 HOME 后要运行多少其他的程序,自然也不知道 activityA 是否会被销毁,所以系统会调用 onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
2、长按HOME键,选择运行其他的程序时。
3、按下电源按键(关闭屏幕显示)时。
4、从activity A中启动一个新的 activity 时。
5、屏幕方向切换时,例如从竖屏切换到横屏时。
在屏幕切换之前,系统会销毁 activity A,在屏幕切换之后系统又会自动地创建 activity A,所以onSaveInstanceState 一定会被执行。这个在 Android开发艺术探索 里介绍的比较详细。而且还有 demo(可以想一下如果不是系统给我们保存了信息为啥你旋转屏幕后还会出现之前你在看的界面和你正在编辑的未完成的信息呢是吧。 系统:这都是我做的,厉不厉害,没我不行吧。。。所以不要肆意(操)玩(做)弄我。。)
总而言之,onSaveInstanceState 的调用遵循一个重要原则,即当系统 “未经你许可” 时销毁了你的activity,则onSaveInstanceState 会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。 ———划重点划重点划重点 。。
Q:onSaveInstanceState() 与 onPause() 的区别?
有时候会出现这样的问题,童鞋们还记得我开头咋说的嘛,onPause 是在 Activity 不可见的时候调用,一般之后就会调用 onStop 方法,这是生命周期方法。就像人都会经过 幼儿 -- 少年 -- 青少年 -- 成年 -- 老年 -- 死亡 一样,躲不开的。但 onSaveInstanceState 方法不一样,它是由系统调用而不是程序员们调用。具体的发生时机也不能确定。作用是保存实例状态,相信我在上面已经介绍的很详细了。
系统异常终止时,调用onSavaInstanceState来保存状态。该方法调用在onStop之前,但和onPause没有时序关系。
onSaveInstanceState 与 onPause 的区别: 前者适用于对临时性状态的保存,而后者适用于对数据的持久化保存。
Activity被重新创建时,调用 onRestoreInstanceState(该方法在 onStart 之后),并将onSavaInstanceState保存的Bundle对象作为参数传到 onRestoreInstanceState 与onCreate 方法。
可通过 onRestoreInstanceState(Bundle savedInstanceState) 和 onCreate((Bundle savedInstanceState) 来判断Activity是否被重建,并取出数据进行恢复。但需要注意的是,在 onCreate 取出数据时一定要先判断 savedInstanceState 是否为空。另外,谷歌更推荐使用 onRestoreInstanceState 进行数据恢复。