一句话总结:
onSaveInstanceState 是“紧急备份员”,在界面被销毁前保存数据;onRestoreInstanceState 是“数据恢复师”,在界面重建后恢复数据——两者配合,让应用像游戏存档一样,意外退出也能恢复现场!
核心区别对比表
| 对比项 | onSaveInstanceState | onRestoreInstanceState |
|---|---|---|
| 调用时机 | Activity 可能被销毁前(如屏幕旋转、内存不足) | Activity 重建后(在 onStart 之后) |
| 主要作用 | 保存临时数据(如输入框内容、滚动位置) | 恢复保存的临时数据 |
| 数据存储位置 | 存入 Bundle | 从 Bundle 读取 |
| 默认行为 | 自动保存部分 View 状态(如 EditText 文本) | 自动恢复这些 View 状态 |
| 是否必须重写 | 按需保存额外数据 | 按需恢复额外数据 |
详细解释(现实比喻)
1. onSaveInstanceState —— “紧急备份员”
-
触发场景:当系统因配置变更(如旋转屏幕)或内存不足要销毁 Activity 时,立即调用。
-
作用:把需要恢复的数据(比如用户输入的文字、列表滚动位置)存入一个“保险箱”(Bundle)。
-
代码示例:
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString("inputText", editText.text.toString()) }
2. onRestoreInstanceState —— “数据恢复师”
-
触发场景:Activity 被系统重建后(比如旋转屏幕回来),在
onStart之后调用。 -
作用:从“保险箱”(Bundle)取出数据,恢复界面状态。
-
代码示例:
override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) val savedText = savedInstanceState.getString("inputText") editText.setText(savedText) }
为什么不用 onCreate 恢复数据?
-
区别对比:
onCreate的 Bundle:可能为null(首次创建 Activity 时)。onRestoreInstanceState的 Bundle:保证非null(只在恢复时调用)。
-
推荐做法:
-
简单数据可在
onCreate恢复:override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState != null) { val savedText = savedInstanceState.getString("inputText") editText.setText(savedText) } } -
复杂数据建议在
onRestoreInstanceState恢复:- 此时所有 View 已完成初始化,避免空指针。
-
默认行为(系统自动帮你做的事)
-
自动保存的 View 状态:
EditText的文本内容。ListView/RecyclerView的滚动位置。CheckBox的选中状态等。
-
自定义 View 需手动处理:
- 重写
onSaveInstanceState()和onRestoreInstanceState()。
- 重写
避坑指南
- 不要保存大量数据:Bundle 有大小限制(通常 1MB),超限会崩溃。
- 敏感数据勿存:Bundle 可能被临时存储在磁盘,需加密处理。
- 用户主动退出不触发:按返回键退出时,需在
onPause或onDestroy持久化数据。
实际场景示例
场景 1:屏幕旋转后恢复输入框内容
- 系统自动处理:如果布局中有
EditText,旋转后内容自动保留(无需额外代码)。
场景 2:自定义 View 的绘制状态保存
-
手动实现:
class MyView(context: Context) : View(context) { private var progress: Int = 0 override fun onSaveInstanceState(): Parcelable { val bundle = Bundle() bundle.putInt("progress", progress) bundle.putParcelable("superState", super.onSaveInstanceState()) return bundle } override fun onRestoreInstanceState(state: Parcelable?) { val bundle = state as Bundle progress = bundle.getInt("progress") super.onRestoreInstanceState(bundle.getParcelable("superState")) } }
总结口诀
“save 像存档,紧急时刻存数据,
restore 像读档,恢复现场不费力。
View 状态系统管,自定义需手动理,
避开大文件和敏感,旋转崩溃成回忆!”