关于Android 的 onSaveInstanceState() 与 onRestoreInstanceState()

本文详细介绍了Activity中onSaveInstanceState()和onRestoreInstanceState()方法,用于状态的保存与恢复。onSaveInstanceState()不一定被触发,主动销毁Activity时不调用;触发它也不一定触发onRestoreInstanceState()。保存和恢复View层次结构基于委托思想,Activity委托Window,Window委托顶级容器,顶级容器通知子View。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文章:onSaveInstanceState 和 onRestoreInstanceState详解


onSaveInstanceState()onRestoreInstanceState() 是关于 Activity 中状态的保存与恢复的方法。

当然在 View 中也存在这一组方法,而 Fragment 则比较特殊,只有 onSaveInstanceState() 而没有 onRestoreInstanceState()(可以参阅 [译]Android Activity 和 Fragment 状态保存与恢复的最佳实践 进一步了解)。

而实际上,Activity 中 onSaveInstanceState()onRestoreInstanceState() 的实现(以及 Fragment 中的 onSaveInstanceState())就是基于 View 的对应的那一组方法实现的。


在自己的 Activity 中,可以重写那一组方法,用于实现自身需要的状态的保存与恢复。

需要注意的是:
1、super.onSaveInstanceState(outState) 会默认实现自动保存 Activity 中的某些状态数据,如 UI 控件的状态等,比如一个 EditText,输入了某些内容,这些内容会在必要的时机被保存下来。

2、super.onRestoreInstanceState(savedInstanceState) 则实现了自动恢复在 super.onSaveInstanceState(outState) 中保存的状态数据,如前面说的 EditText 中输入的被保存的内容。

注意!注意!注意!这里说的是父类的对应的方法。如果在自己的 Activity 中没有调用父类的方法,则无法实现 Activity 中某些状态数据的保存与恢复。

且实现上述两点的前提是需要为 View 设置 id 属性。


(1) onSaveInstanceState() 并不一定被触发

onSaveInstanceState() 的调用遵循一个重要原则,即当 系统存在 “未经你许可” 时销毁我们的 activity 的可能 时,则onSaveInstanceState() 会被系统调用。这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然是否把握机会保存则是由开发者自行把握)。

被调用的时机可能发生在 onPause() 或者 onStop() 之前。但是通常情况下是在 onPause() 和 onStop() 之间调用。

但是当用户主动去销毁一个 Activity 时,例如在应用中按返回键,onSaveInstanceState() 就不会被调用。因为在这种情况下,用户的行为决定了不需要保存 Activity 的状态。

onSaveInstanceState() 会被调用的几种情景:

(1)、当用户按下HOME键时。
(2)、长按HOME键,选择运行其他的程序时。
(3)、按下电源按键(关闭屏幕显示)时。
(4)、从 activity A 中启动一个新的 activity 时。
(5)、屏幕方向切换时,例如从竖屏切换到横屏时。
(6)、更改设备语言等。

onSaveInstanceState() 只适合用于保存一些临时性的状态,而 onPause() 适合用于数据的持久化保存。

(2) 触发了 onSaveInstanceState() ,也不一定会触发 onRestoreInstanceState()

因此 Activity 不一定有被系统销毁重建。

但是触发了 onRestoreInstanceState(),前提一定是有通过 onSaveInstanceState() 保存了数据(准确的说是生成并保存了对应的 bundle 实例,这里的 bundle 的实例化与保存是在系统源码中实现的)。

如果触发了 onRestoreInstanceState(bundle),则在 onCreate(bundle) 中也会传递对应的 bundle 实例(即此时 onCreate() 方法传递来的 bundle 不为空)。

且 onCreate() 和 onRestoreInstanceState() 中传递过来的 Bundle 实例是同一个。

(3) 关于保存和恢复 View 层次结构

Activity#onSaveInstanceState() 被触发,保存 View 层次结构的内容时,Activity 会委托 Window 去保存数据,接着 Window 再委托它上面的顶级容器去保存数据,顶级容器是一个 ViewGroup,一般来说很有可能是 DecorView。最后顶级容器再一一通知子 View 来保存数据。

基于委托的思想。

Android中,`EditText` 的内容需要在Activity销毁(如用户旋转设备、按Home键等)后保存,并在下次启动时恢复,这通常通过重写 ` onSaveInstanceState()` 和 ` onRestoreInstanceState()` 来实现。这两个方法分别用于保存和恢复组件的状态。 首先,在`onSaveInstanceState(Bundle outState)` 中,我们需要将 `EditText` 的文本添加到`Bundle`中: ```java @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 获取EditText实例并保存其文本 EditText editText = findViewById(R.id.edit_text_id); String text = editText.getText().toString(); // 将文本存入Bundle outState.putString("edit_text_data", text); } ``` 然后,在`onCreate(Bundle savedInstanceState)` 或者 `onRestoreInstanceState(Bundle savedInstanceState)` 中,我们在Activity复原时从`Bundle`中恢复文本: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { // 如果存在先前的状态数据 String savedText = savedInstanceState.getString("edit_text_data"); if (savedText != null) { // 从 Bundle 中获取并设置回 EditText EditText editText = findViewById(R.id.edit_text_id); editText.setText(savedText); } } } // 当 Activity 被恢复时,也可以在这里调用 @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // 恢复 EditText 文本同上 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值