onSaveInstanceState执行时机

本文详细解析了Android中onSaveInstanceState方法的触发条件及其与onRestoreInstanceState的关系,包括不同场景下的执行时机,如屏幕旋转、启动新Activity等。
        当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?通过重写一个activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我们可以清楚地知道当某个activity(假定为activity A)显示在当前task的最上层时,其onSaveInstanceState方法会在什么时候被执行,有这么几种情况: 
1、当用户按下HOME键时。 
这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则 
2、长按HOME键,选择运行其他的程序时。 
3、按下电源按键(关闭屏幕显示)时。 
4、从activity A中启动一个新的activity时。 
5、屏幕方向切换时,例如从竖屏切换到横屏时。
 
在屏幕切换之前,系统会销毁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方法中做数据还原。
 
`onSaveInstanceState()` 的调用时机是: > **在 Activity 可能被系统异常销毁之前调用,用于保存 UI 状态数据。** --- ## ✅ 调用时机详解 ### 📌 触发时机: - 当系统**预测当前 Activity 可能会被销毁并重建时**(非用户主动 finish)。 - 通常发生在以下场景: | 场景 | 是否调用 onSaveInstanceState | |------|----------------------------| | 横竖屏切换(配置变更) | ✅ 是 | | 用户按下 Home 键退出应用 | ✅ 是 | | 系统资源不足导致后台 Activity 被杀死 | ✅ 是 | | 用户按下返回键关闭 Activity | ❌ 否 | | 主动调用 `finish()` | ❌ 否 | | 应用进入后台后被系统杀死 | ✅ 是(如果之前有机会执行) | --- ## ✅ 生命周期中调用顺序 `onSaveInstanceState()` 通常在以下生命周期方法之间被调用: ``` onPause() → onSaveInstanceState() → onStop() ``` > 注意:`onSaveInstanceState()` 是在 `onPause()` 之后、`onStop()` 之前调用的。 --- ## ✅ 方法作用 - 用于**保存 UI 相关的状态**,比如 EditText 输入内容、滚动位置、临时变量等。 - 保存的数据通过 `Bundle` 传递,并在 Activity 重建时通过 `onCreate()` 或 `onRestoreInstanceState()` 恢复。 --- ## ✅ 示例代码 ```java @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存 UI 数据 outState.putString("username", editText.getText().toString()); outState.putInt("scrollPosition", scrollView.getScrollY()); } ``` --- ## ✅ 开发建议 | 建议 | 说明 | |------|------| | ✅ 保存轻量数据 | `Bundle` 有大小限制(建议不超过 1MB) | | ✅ 避免保存敏感数据 | 如密码,建议使用 ViewModel 或持久化存储 | | ✅ 使用 Parcelable 保存复杂对象 | 支持自定义对象的序列化 | | ✅ 不要在该方法中执行耗时操作 | 会影响 Activity 生命周期响应速度 | --- ## ✅ 与 ViewModel 的区别 | 方式 | 是否受生命周期影响 | 是否适合保存 UI 状态 | 是否适用于配置变更 | |------|------------------|---------------------|---------------------| | `onSaveInstanceState()` | 是 | ✅ 适合保存简单状态 | ✅ 是 | | `ViewModel` | 否(存活于配置变更) | ✅ 更适合保存复杂状态 | ✅ 是(不会重建) | --- ## ✅ 生命周期流程图(异常销毁时) ``` onPause() → onSaveInstanceState() → onStop() → onDestroy() → 重建时:onCreate() → onStart() → onRestoreInstanceState() → onResume() ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值