一句话说透Android里面的onSaveInstanceState和onRestoreInstanceState的区别

459 阅读2分钟

一句话总结:

onSaveInstanceState 是“紧急备份员”,在界面被销毁前保存数据;onRestoreInstanceState 是“数据恢复师”,在界面重建后恢复数据——两者配合,让应用像游戏存档一样,意外退出也能恢复现场!


核心区别对比表

对比项onSaveInstanceStateonRestoreInstanceState
调用时机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()

避坑指南

  1. 不要保存大量数据:Bundle 有大小限制(通常 1MB),超限会崩溃。
  2. 敏感数据勿存:Bundle 可能被临时存储在磁盘,需加密处理。
  3. 用户主动退出不触发:按返回键退出时,需在 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 状态系统管,自定义需手动理,
避开大文件和敏感,旋转崩溃成回忆!”