转载自onSaveInstanceState方法什么时候被调用?(转载/整理)

  • 在 Activity 被销毁之前被调用来保存每个实例的状态,这样就可以保证该状态能够从 onCreate(Bundle) 或者onRestoreInstanceState(Bundle)恢复过来。 本方法在 Activity 可能被销毁前调用,这样当该 Activity 在将来某个时刻重新回来时可以恢复其之前的状态。例如,如果 Activity B 启用后位于 Activity A 的前端,在某个时刻 Activity A 因为系统回收资源的原因要被销毁,Activity A 有机会通过 onSaveInstanceState() 来保存其用户界面状态,使得将来用户返回到 Activity A 的时候能够通过 onCreate(Bundle) 或者onRestoreInstanceState(Bundle) 来恢复其界面状态。不要将这个方法和 Activity 生命周期中的回调如 onPause() 或 onStop() 搞混淆了,onPause() 在 Activtiy 被放置到后台或者自行销毁时总会被调用,onStop() 在 Activity 被销毁时被调用。一个会调用 onPause() 和 onStop() 但不会触发 onSaveInstanceState() 的例子是当用户从 Activity B 返回到 Activity A 时:没有必要调用 B 的 onSaveInstanceState(Bundle)方法,因为此时的 B 实例永远不会被恢复,因此系统会避免调用它。一个调用 onPause() 但不调用 onSaveInstanceState(Bundle) 方法的例子是当 Activity B 启动后处在 Activity A 的前端:如果在B的整个生命周期里 A 的用户界面状态都没有被破坏的话,系统是不会调用 Activity A 的onSaveInstanceState(Bundle)方法。默认的实现负责了大部分 UI 实例状态的保存,采用的方式是调用 UI 层上每个拥有 id 的 view 的 onSaveInstanceState()方法 ,并且保存当前获得焦点的 view 的 id (所有保存的状态信息都会在默认的 onRestoreInstanceState(Bundle) 实现中恢复)。如果你覆写这个方法来保存额外的没有被各个view保存的信息,你可能想要在默认实现过程中调用或者自己保存每个视图的所有状态。如果被调用,这个方法会在 onStop() 前被触发,但系统并不保证是否在 onPause() 之前或者之后触发。

  • Activity 中的 onSaveInstanceState() 方法和 onRestoreInstanceState() 方法并不是生命周期方法,它们不同于 onCreate()、onPause() 等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键),由系统销毁一个 Activity 时,onSaveInstanceState() 方法就会被调用。但是当用户主动去销毁一个 Activity 时,例如在应用中按返回键,onSaveInstanceState() 方法就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState() 方法只适合用于保存一些临时性的状态,而onPause() 方法适合用于数据的持久化保存。 另外,当屏幕的方向发生了改变, Activity 会被销毁并重新创建,如果你想在 Activity 被销毁前缓存一些数据,并且在 Activity 被重新创建后恢复缓存的数据。可以重写 Activity 中的 onSaveInstanceState() 方法和 onRestoreInstanceState()方法,如下:

    public class PreferencesActivity extends Activity {private String name;protected void onRestoreInstanceState(Bundle savedInstanceState) {// 重新创建后恢复缓存的数据name = savedInstanceState.getString("name");super.onRestoreInstanceState(savedInstanceState);}protected void onSaveInstanceState(Bundle outState) {// 被销毁前缓存一些数据outState.putString("name", "l_yqing");super.onSaveInstanceState(outState);}
    } 
  • 当用户启动一个新 Activity 之后,之前的 Activity 可能在内存中处于停止状态也可能由于新 Activity 需要更多内存而被系统销毁了,但不论怎样,当用户在新 Activity 上点击返回键时,他希望看到的是原先的 Activity 的界面。原先的 Activity 如果是被重新创建的,那么它就要恢复到用户最后看到它时的样子,我们该怎么做呢?其实也不难,在 onPause() 、onStop() 或 onDestroy() 中保存必要的数据就行了。但是现在Google又冒出一个新的东西:onSaveInstanceState(),观其名可知其意:它是专门用来保存实例状态的,这个“实例”不是指的 Activity 对象,而是它所在的进程,因为Activity 的销毁是因为它所在的进程被杀掉而造成的。onSaveInstanceState()是在系统感觉需要销毁Activity时调用的,它被传入一个参数Bundle,这个Bundle可以被认为是个 Map 字典之类的东西,用“键-值”的形式来保存数据。现在又叫人蛋疼了:不是可以在 onPause() 中保存数据吗?为什么又搞出这样一个家伙来?它们之间是什么关系呢? 原来,onSaveInstanceState() 方法的主要目的是保存和 Activity 的状态有关的数据,当系统在销毁 Activity 时,如果它希望 Activity 下次出现的样子跟之前完全一样,那么它就会调用onSaveInstanceState(),否则就不调用。所以要明白这一点:onSaveInstanceState() 方法并不是永远都会调用。比如,当用户在一个 Activity 点击返回键时,就不会调用,因为用户此时明确知道这个 Activity 是要被销毁的,并不期望下次它的样子跟现在一样(当然开发者可以使它保持临死时的表情,你非要这样做,系统也没办法),所以就不用调用onSaveInstanceState()。现在应该明白了:在onPause()、onStop() 以及 onDestroy() 中需要保存的是那些需要永久化的数据,而不是保存用于恢复状态的数据,状态数据有专门的方法:onSaveInstanceState()。数据保存在一个 Bundle 中,Bundle 被系统永久化。当再调用 Activity 的onCreate()时,原先保存的 Bundle就被传入,以恢复上一次临死时的模样,如果上次被销毁时没有保存 Bundle,则为 null。 还没完呢,如果你没有实现自己的 onSaveInstanceState(),但是 Activity 上控件的样子可能依然能被保存并恢复。原来 Activity 类已实现了onSaveInstanceState(),在 onSaveInstanceState() 的默认实现中,会调用所有控件的相关方法,把控件们的状态都保存下来,比如 EditText 中输入的文字、CheckBox 是否被选中等等。然而不是所有的控件都能被保存,这取决于你是否在 layout 文件中为控件赋了一个名字(android:id)。有名的就存,无名的不管。既然有现成的可用,那么我们到底还要不要自己实现 onSaveInstanceState() 方法呢?这就得看情况了,如果你自己的派生类中有变量影响到UI,或你程序的行为,当然就要把这个变量也保存了,那么就需要自己实现,否则就不需要,但大多数情况肯定需要自己实现一下下了。对了,别忘了在你的实现中调用父类的 onSaveInstanceState() 方法。
    注:由于 onSaveInstanceState() 方法并不是在每次被销毁时都会调用,所以不要在其中保存那些需要永久化的数据,执行保存那些数据的最好地方是在 onPause() 方法中。

转自heiguy的专栏onSaveInstanceState和onRestoreInstanceState触发的时机

先看Application Fundamentals上的一段话:

Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action (such as pressing the BACK key) 从这句话可以知道,当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。 注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?通过重写一个activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我们可以清楚地知道当某个activity(假定为activity A)显示在当前task的最上层时,

其onSaveInstanceState方法会在什么时候被执行,有这么几种情况:

  • 当用户按下HOME键时。 这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
  • 长按HOME键,选择运行其他的程序时。
  • 按下电源按键(关闭屏幕显示)时。
  • 从activity A中启动一个新的activity时。
  • 屏幕方向切换时,例如从竖屏切换到横屏时。

在屏幕切换之前,系统会销毁activity A,在屏幕切换之后系统又会自动地创建activity A,所以onSaveInstanceState一定会被执行 总而言之,onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。

至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的,onRestoreInstanceState被调用的前提是,activity A“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用,例如,当正在显示activity A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行

另外,onRestoreInstanceState的bundle参数也会传递到onCreate方法中,你也可以选择在onCreate方法中做数据还原。

Android应用开发—onSaveInstanceState方法什么时候被调用?相关推荐

  1. android 实现发送彩信方法 (MMS),非调用系统彩信界面

    最近有个需求,不去调用系统界面发送彩信功能.做过发送短信功能的同学可能第一反应是这样: 不使用 StartActivity,像发短信那样,调用一个类似于发短信的方法 SmsManager smsMan ...

  2. Android Light开发(二) 通知灯调用过程

    Android中有各种灯,背光灯,按键灯,指示灯,等等:前几天修改了这部分代码,整理下思路,其实都不难: 首先,来说说指示灯(提示灯),即未接电话,未接短信的时候,会闪灯,这个其实就是Notifica ...

  3. Android游戏开发实践指南(华章程序员书库)

    <Android游戏开发实践指南(华章程序员书库)> 基本信息 原书名:Learning Android Game Programming:A Hands-On Guide to Buil ...

  4. Android工程开发笔记一

    Android工程开发笔记<一> ---------------------------------------不同 APP相互调用 activity 1.ComponentName() ...

  5. android数据库三个方法有哪些,一个三年Android开发的总结 - 常见数据库问题总结...

    Android应用开发离不开对SQLite数据库的操作,一般简单的增删改查,可以直接通过SQLiteDatabase进行,但是只要操作变得频繁,并且随着需求不断增加,你应该考虑使用ORM框架,至少使用 ...

  6. 《Android游戏开发详解》——第1章,第1.6节函数(在Java中称为“方法”更好)...

    本节书摘来自异步社区<Android游戏开发详解>一书中的第1章,第1.6节函数(在Java中称为"方法"更好),作者 [美]Jonathan S. Harbour,更 ...

  7. 【Android FFMPEG 开发】C++ 回调 Java 方法 模板 ( JavaVM *vm | JNIEnv *env | jobject instance | 引用类型 | 模板代码示例 )

    文章目录 I . Native 调用 Java 方法 II . JNIEnv *env 与 jobject instance III . JavaVM *vm IV . 局部引用 与 全局引用 分析 ...

  8. 【Android NDK 开发】JNI 方法解析 ( JNIEnv *env 参数 )

    文章目录 一. JNI 方法解析 二. JNIEnv *env 参数解析 三. C 语言 环境中 JNIEnv *env 参数解析 四. C ++ 环境中 JNIEnv *env 参数解析 总结 : ...

  9. 【Android NDK 开发】Visual Studio 2019 使用 CMake 开发 JNI 动态库 ( 动态库编译配置 | JNI 头文件导入 | JNI 方法命名规范 )

    文章目录 I . JNI 与 NDK 区别 II . Visual Studio 编译动态库 III. 配置 导入 jni.h 头文件 IV . IntelliJ IDEA Community Edi ...

最新文章

  1. listen函数的第二个参数_【图像处理】OpenCV系列十七 --- 几何图像变换函数详解(一)...
  2. Python基础-小程序练习(跳出多层循环,购物车,多级菜单,用户登录)
  3. HiccDS共享音乐列表
  4. JavaScript的10种跨域共享的方法
  5. LeakCanary上传 leak trace 到服务器
  6. Pandas里面dataframe 中loc和iloc函数的区别
  7. canvas 绘制直线 并选中_canvas绘制飞线效果
  8. 成都链安科技CEO 创始人杨霞:解决智能合约的安全问题,形式化验证是个“利器”!
  9. 论文投稿 基金名称 标准版 中英文
  10. QQ微信实现连续发送消息【代码实现】
  11. 由word制作CHM文件
  12. python+request 哔哩哔哩视频下载
  13. 机房环动监控系统作用
  14. 对坐标的曲线积分求做功_对坐标的曲线积分对弧长的曲线积分 二重积分
  15. 真的有必要定义VO,BO,PO,DO,DTO吗?
  16. js 原生cookie封装
  17. 目标检测0-02:YOLO V3-网络结构输入输出解析
  18. 信息学 计算机奥林匹克竞赛辅导,震惊!信息学奥赛好处竟然这么多
  19. 多线程模拟实现百米赛跑
  20. 2月第二周安全要闻回顾:微软发通缉令 IBM关注犯罪

热门文章

  1. 《Java8实战》笔记(02):通过行为参数传递代码
  2. 《深入理解JVM.2nd》笔记(四):虚拟机性能监控与故障处理工具
  3. netflow流量分析工具 linux,Centos5/Linux安装Nfdump和Nfsen图形界面分析netflow数据
  4. STL源码剖析 stack 栈 概述->(使用deque双端队列 / list链表)作为stack的底层容器
  5. 循序渐进学好编程,不要太急!!!
  6. 《 Docker 进阶与实战 》 读书笔记
  7. Docker 方式安装 Nginx 、阿里云服务器上装 Ngnix
  8. 需求规格说明书1.0
  9. 如何提高UDP的可靠性
  10. 【原】Spark中Master源码分析(一)