设为首页 加入收藏

TOP

Android 组件系列-----Activity保存状态(一)
2015-08-31 21:23:39 来源: 作者: 【 】 浏览:60
Tags:Android 组件 系列 -----Activity 保存 状态

本篇随笔将详细的讲解Activity保存状态的概念,也就是saving activity state。


一、Activity状态保持概念


保存Activity的状态是非常重要的,例如我们在玩一个游戏的时候,突然来了一个电话,这个时候在接听完电话之后我们返回到游戏中,这个时候我们希望游戏还是之前那个进度,或者说发生突发事件,游戏这个应用程序被关闭了,这个时候我们如果再重新打开游戏的话,我们如果还是希望回到之前的进度,我们就需要将其状态保存起来,这样在Activity的摧毁时,我们还能够根据保存的状态回到之前的进度。这就是Activity的状态保存。


二、两种方式的情况下Activity的状态会被保存



1.当一个Activity位于另一个Activity的前面时,也就是另一个Activity处于stop状态,这个时候这个Activity仍然占用着内存,并且保持着Activity的状态,如果此时点击后退按钮,那么此时第一个Activity又会重新回到前台界面上,此时这个Activity会保持原来的状态,我们不需要重新获得其状态。


2.当我们的这个Activity处于stop状态在后台时,如果此时有一个优先级别更高的Activity需要获得资源,此时系统可能会破坏处于stop状态的Activity,回收其内存,此时这个Activity对象会被destroyed,此时如果我们必须调用一个 onSaveInstanceState() 方法来保存我们的Activity的对象状态。


onSaveInstanceState(Bundle outState)这个方法接受一个Bundle类型参数,我们可以将我们需要保存的状态通过Bundle的 putString, putInt 方法保存起来。


当我们的Activity处于极易被摧毁的时候,系统会调用 onSaveInstanceState() 方法,如果此时系统杀死了这个Activity的线程,这个Activity对象被destroy后,再打开这个Activity时,又会重新创建这个Activity,这个时候系统会将 onSaveInstanceState 方法中的 Bundle 对象传递给Activity的 onCreate()和 onRestoreInstanceState() 方法,


使用这两个方法中的任何一个,我们都可以根据之前保存的 Bundle 对象来恢复我们Activity之前的状态。


三、onSaveInstanceState方法


下面我们具体看看这个方法,通过这个方法我们可以在一个Activity被杀死时,并在将来如果要重新创建这个Activity时可以恢复其保存的状态。我们不需要疑惑这个方法和Activity生命周期函数方法的调用时期,例如onPause()方法,当一个Activity处于后台时或者容易受到破坏时,这个方法就会被调用。


有两种情况是不会调用这个onSaveInstanceState方法的:


①activity B 位于 activity A的前面,此时如果点击 Back 按钮,activity B 会分别调用 onPause、onStop方法,此时系统并不会调用 onSaveInstanceState() 方法,因为此时是我们显示的关闭activity B,所以系统认为调用?onSaveInstanceState() 是没有并要的。


②activity B 位于 activity A的前面,此时activity A处于后台状态,但是还是占用了内存资源,当通过Back 按钮,使得activity A重新回到前台时,onSaveInstanceState()方法也是没有必要调用的,因为此时activity A本身就完整的保存了当前的状态。?


接下来我们通过一个实例来看看通过Activity的?onSaveInstanceState() 、onCreate()以及onRestoreInstanceState()方法的调用来保持我们Activity的状态。


我们看到,在这个Activity中,我们实现了其 onSaveInstanceState()、onCreate()和onRestoreInstanceState()方法,我们在?onSaveInstanceState() 方法中将当前的Activity的状态保存下来:


然后在onCreate()方法和onRestoreInstanceState() 方法中试图得到保存的Bundle对象,当Activity第一次被创建的时候,onCreate()和onRestoreInstanceState()方法中的Bundle对象是null的


我们在这两个方法里分别使用 Toast 的弹出框来看看是否能将Bundle保存的状态值打印出来。我们为了模拟这个实验,需要通过将手机屏幕的横竖屏进行切换。


当屏幕的方向被改变的时候,系统会首先destroy然后recreate这个Activity对象来根据我们配置的资源文件重新加载界面,这个时候保存我们的Activity的状态是非常重要的,因为在大多数情况下,屏幕放心的改变是经常发生的事,所以这个时候我们必须通过 onSaveInstanceState() 方法来保存我们的Activity的状态。


我们来看看实验结果:




我们看到,当我们反转屏幕的时候,因为之前已经通过 onSaveInstanceState()方法保存了Activity的状态,所以在Activity从destroy到recreate时,会将保存的Bundle对象传给onCreate和onRestoreInstanceState方法,此时我们就能够恢复我们Activity的状态了。


四、Android View控件的onSaveInstanceState()方法


当我们在创建一个Activity对象的时候,我们如果没有重写父类的?onSaveInstanceState()方法,此时我们的一些Activity状态也会通过调用父类Activity的默认的?onSaveInstanceState()方法来保存下来。特别地:父类的onSaveInstanceState()方法会调用布局文件中每一个View对象的相应的?onSaveInstanceState()方法 来保持各自的状态。在Android的大多数的widget控件都非常好的实现了?onSaveInstanceState()方法,因此我们对这些空间的值的改变都会被自动的保存下来。例如我们的EditText、Checkbox控件,当我们在输入了我们的值只会,当Activity被destroy-->recreate的时候,此时我们的值仍然会被保存下来,前提是如果我们需要保存一个View控件的状态,我们必须要给其指定一个唯一的标识符(通过 android:id 属性来指定),如果我们没有指定的话,系统则不会保存其状态。例如我们来看一下下面这个例子:


我们这个Activity的界面一共有5个View控件,其中username这个EditText我们指定了ID,email这个EditText没有指定ID,而下面的三个CheckBox,只有最后一个CheckBox没有为其指定ID,我们来看看,当这个Activity被重新创建时,其会不会保存每个View控件的状态:



我们在两个文本框中输入了值,然

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android 组件系列-----Activity的.. 下一篇Broadcom移植到OpenWrt总结

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: