onSaveInstanceState 是什么?

onSaveInstanceState(outState: Bundle) 是 Activity / Fragment 生命周期中的一个回调,系统在组件可能被销毁但需要后续恢复时调用,让你把关键状态保存到一个 Bundle 中。

你可以理解为:系统在说”我可能要杀掉你了,赶紧把重要的东西存一下,等会儿我帮你恢复”。

什么时候会触发?

  • 屏幕旋转 — Activity 会销毁重建(Configuration Change)
  • 按 Home 键 — Activity 进后台,可能被系统回收
  • 切换到其他 App — 同上
  • 多窗口模式切换
  • 系统内存不足 — 后台 Activity 被杀

⚠️ 用户主动按返回键退出时不会调用 onSaveInstanceState,因为这是用户明确的销毁意图。

工作流程

Activity 即将不可见
  → 系统调用 onSaveInstanceState(bundle)
  → 你把关键数据存入 bundle
  → Activity 被销毁
  → 用户返回时,系统重建 Activity
  → onCreate(savedInstanceState) / onRestoreInstanceState() 中恢复数据

基本用法

// 保存状态
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putInt("score", currentScore)
    outState.putString("name", userName)
}
 
// 恢复状态 — 方式一:在 onCreate 中
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    savedInstanceState?.let {
        currentScore = it.getInt("score")
        userName = it.getString("name")
    }
}
 
// 恢复状态 — 方式二:在 onRestoreInstanceState 中
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
    currentScore = savedInstanceState.getInt("score")
}

调用时机(相对于生命周期)

  • API 28+(Android P):在 onStop() 之后调用
  • API 28 之前:在 onStop() 之前调用,但不保证在 onPause() 之前还是之后
onPause()

onStop()

onSaveInstanceState()   ← API 28+ 的调用时机

FragmentActivity 的默认行为

FragmentActivity(AppCompatActivity 的父类)在 onSaveInstanceState() 的默认实现中会:

  1. 保存所有 Fragment 的状态
  2. 把 Intent 的 extras 也序列化到 Bundle 中

⚠️ 第 2 点很关键——如果 Intent extras 中有大数据(如大型 HashMap),这里会再次序列化,可能触发 TransactionTooLargeException

防御性写法:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    // 清除 Intent extras,防止大数据被二次序列化
    intent?.removeExtra(PARAMS)
}

注意事项

  1. Bundle 也有大小限制 — 和 Intent 一样走 Binder,总共 ~1MB
  2. 只存轻量数据 — 适合存 ID、位置、用户输入等;大数据用 ViewModel、Room、文件等
  3. 和 ViewModel 的区别
特性onSaveInstanceStateViewModel
配置更改(如旋转)后存活
进程被杀后恢复
适合数据量小(Bundle ~1MB 限制)大(内存级别)
最佳实践两者配合使用两者配合使用

相关笔记