Android有个机制,没有被程序主动销毁的Activity会被放入内存,其销毁由系统根据内存使用情况进行控制。所以在后台的Activity什么时候会被系统干掉我们没办法预见,而且被系统干掉的Activity,系统有时候会帮我们重新创建。
其实onSaveInstanceState()主要用来辅助系统重新创建Activity时恢复数据的,因为不重新创建的话,也没必要用onSaveInstanceState()保存数据,而且该重建完全是系统来做的,不是我们主动去调用的。
举个例子来说明:调用系统拍照,拍好照后将照片再显示于我们的Activity上。
正常过程如下:MyActivity1->拍照功能-->MyActivity1。
但是当内存不太够用时,我们的Activity在打开拍照功能后,很容易被系统主动干掉,这是因为拍照要消耗大量资源。但是MyActivity被干掉后,从拍照程序返回,系统为保证这一过程的完整性,会再帮我们主动创建一个MyActivity。
销毁重建过程如下:MyActivity1->拍照功能-->MyActivity2。
这样就出现问题了,MyActivity1与MyActivity2是同一类的两个不同的对象,而MyActivity1中由于用户的操作,会创建一些对象,而系统在创建MyActivity2时,只会调用Activity创建时需要的生命周期函数,最后在MyActivity2中一部分对象丢失了。这时onSaveInstanceState()出场了,它可以保存我们创建的对象,然后供恢复用。
Bundle中的数据保存到了哪里?
该问题本人查了很多资料也没有找到明确的答案,只能推导一下了。有个明确的说法是onSaveInstanceState()不能保存持久性数据,通过这个说法,数据应该不是保存到了SD卡中,那么只能是保存在内存中了。
经过测试,发现不同进程之间调用时,在进程被干掉之前用onSaveInstanceState()保存的数据,在返回后,系统帮忙重新建的进程能恢复数据。这说明一个问题,即Bundle中的数据不是保存在应用所属的进程内存里。参考到Bundle中的对象必须要序列化,或者实现Parcelable接口,不管如何,肯定是为了进程间通信用的。
所以本人认为Bundle中的数据保存到了系统级进程中的内存里。只要系统没崩溃,保存的数据都能恢复过来。
onSaveInstanceState()函数是什么时候被系统调用的?
有个说法:该方法是在系统内存不足时,系统主动销毁Activity前,被调用。
其实该说法不准确,应该是在Activity由前台变为后台时,就会被调用,比如按了Home键或者转跳转到另一个Activity且没被finish,系统都会调用该方法。只要系统认为Activity有被销毁的可能时,就会触发调用,不必等到被销毁前的那一刻。
如何恢复被保存的数据?
很明显恢复里需要用到保存时的Bundle对象,因为保存时填入的值都保存在那里,所以恢复用到它,系统提供了两个回调函数,并在参数中提供该Bundle对象:onCreate(Bundle savedInstanceState)、onRestoreInstanceState(Bundle savedInstanceState)。
是不是onSaveInstanceState被调用了,onCreate中的Bundle就有值或者onRestoreInstanceState函数就会被调用?显然不是的,还原有个条件,即Activity是被系统销毁的,而不是我们主动finish掉的。
有两个函数都能还原,那应该用哪一个呢?这个完全由实际情况来决定,比如有些对象在onCreate中创建的,或者产生的,并且用到了,那么肯定在onCreate中就要还原该对象,其它情况则选其中之一都可以。主要原因就是这两函数的回调时机不一样,onCreate很明显是Activity创建时首个调用的函数,且只要是新创建的,都会调用,而onRestoreInstanceState函数是在onStart后,onResume之前被调用的。
分享到:
相关推荐
通过这个例子描述onSaveInstanceState何时调用。非常简单的小例子。
切换横竖屏,如何保存数据
No boilerplate code like onSaveInstanceState or onRestoreInstanceState any more. Getting started Just add the @AutoRestore annotation to your fields that need to be saved and restored in Activities, ...
在Fragment里面,利用onSaveInstanceState保存数据,并可在onActivityCreated里面恢复数据。 public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ... ...
主要介绍了Android onSaveInstanceState和onRestoreInstanceState触发的时机的相关资料,需要的朋友可以参考下
主要介绍了Android 中 onSaveInstanceState()使用方法详解的相关资料,希望通过本文大家能够掌握这部分知识,需要的朋友可以参考下
Android中,Activity是所有程序的根本,所有程序的流程都运行在Activity之 中,Activity具有自己的生命周期(由系统控制生命周期,程序无法改变,但可 以用onSaveInstanceState保存其状态)。 对于Activity,关键是其...
我们都知道,类似 Activity, Fragment 有 onSaveInstanceState() 回调用来保存状态。 在Fragment里面,利用onSaveInstanceState保存数据,并可在onActivityCreated里面恢复数据。 public void onActivityCreated...
android 内存被回收是一个开发者的常见问题。当我们跳转到一个二级界面,或者切换到后台的时候,如果时间过长或者手机的内存不足,当我们再返回这个界面的时候,activity或fragment就会被内存回收。
在我们接电话的过程中,我们发信息的那个Activity是可能会被系统回收的,这时会调用Activity的onSaveInstanceState回调方法,而我们就可以在这个方法中保存状态数据,在onCreate方法或者在2.0之后提供的回调方法...
里有一些额外的技巧来避免ANR,并有助于让你的应用程序看起来有响应性。 如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度 (ProgressBar和ProgressDialog对这种情况来说很有用)。 特别是游戏...
Activity 横竖屏切换时需要回调两个函数 ,所以在此将这个两个函数暂时看成是Activity 横竖屏切换的生命周期的一部分,这两个函数如下 onSaveInstanceState(Bundle outState) :Activity 即将销毁时保存数据 ...
简单的订单安卓程序,其中包括OnClickListener,TextWatcher,onSaveInstanceState,onRestoreInstanceState,onConfigurationChanged的用法
使用onSaveInstanceState / onRestoreInstanceState重新创建活动。 选择预告片后,应用程序会使用意图启动预告片。 保存旋转时细节活动滚动视图的滚动位置。 可选功能 存储电影海报,剧情简介,用户评分和发行...
这个存储库提供了一种在处理片段传输和后台任务时避免“java.lang.IllegalStateException:Can not perform this action after onSaveInstanceState”的方法。 您可以在的非常权威的阅读有关该问题和可能的解决方案...
Android Fragments and Activities的实例保护程序。 您再也不必编写一百万个公共静态最终字符串了! 背包是一个注释处理器,通过简单注释通常可以在onSaveInstanceState()期间保存到bundle中并在onCreate()中...
当activity实例在后台时, 系统在回收资源时很可能回收掉Activity, 并在onSaveInstanceState函数里保存fragment的状态, 再次打开该Activity时, 在onCreate方法里取出bundle里的fragment状态, 但这时fragment...