onSaveInstanceState状态问题

本文探讨了在Android应用中遇到的java.lang.IllegalStateException异常,即在onSaveInstanceState后进行FragmentManager操作的问题。详细解释了错误原因,并提供了使用commitAllowingStateLoss()方法的解决方案。

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

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1280)
    at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:451)
    at android.app.Activity.onBackPressed(Activity.java:2153)
    at android.app.Activity.onKeyUp(Activity.java:2131)
    at android.view.KeyEvent.dispatch(KeyEvent.java:2633)
    at android.app.Activity.dispatchKeyEvent(Activity.java:2361)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1819)

在你的应用程序被停止的时候,在onSavedInstance()中是不能传递intent的,因为此时上下文已经不可用了吧。。
在这个回调函数中是保存数据状态用的,而不是执行新任务用的。。


API11修复:
说明:http://developer.android.com/reference/android/app/FragmentTransaction.html#commitAllowingStateLoss()

public abstract int commitAllowingStateLoss () Added in API level 11

Like commit() but allows the commit to be executed after an activity's state is saved. This is dangerous

because the commit can be lost if the activity needs to later be restored from its state, so this should

only be used for cases where it is okay for the UI state to change unexpectedly on the user.

大致意思是说我使用的 commit方法是在Activity的onSaveInstanceState()之后调用的,这样会出错,因为onSaveInstanceState

方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后再给它添加Fragment就会出错。解决办法就

是把commit()方法替换成 commitAllowingStateLoss()就行了,其效果是一样的。

### Android 中 `onSaveInstanceState` 的使用方法 #### 1. **`onSaveInstanceState` 的基本功能** `onSaveInstanceState` 是一种机制,允许开发者在 Activity 被系统销毁时保存临时状态信息。这些信息可以通过 Bundle 对象传递给后续的 `onCreate()` 或者 `onRestoreInstanceState()` 方法来恢复界面状态[^3]。 #### 2. **典型场景下的工作流程** 当设备发生配置更改(如屏幕旋转)、内存不足或其他原因导致 Activity 需要重新创建时,系统会自动调用 `onSaveInstanceState` 来保存当前的状态。以下是具体的工作流: - 当系统决定销毁一个 Activity 并可能在未来重建它时,会先调用 `onSaveInstanceState`。 - 开发者可以在此处通过 `Bundle` 参数保存必要的状态数据。 - 如果 Activity 后续被重建,则会在 `onCreate(Bundle)` 或 `onRestoreInstanceState(Bundle)` 中接收到相同的 `Bundle` 数据并完成状态恢复。 #### 3. **代码示例** 以下是一个完整的例子展示如何正确使用 `onSaveInstanceState` 和 `onRestoreInstanceState`: ```java public class MainActivity extends AppCompatActivity { private static final String KEY_OCTOPUS_URL = "octopus_url"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { // 恢复已保存的数据 String url = savedInstanceState.getString(KEY_OCTOPUS_URL); System.out.println("onCreate(): Restored URL -> " + url); } } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // 存储自定义数据到 Bundle 中 outState.putString(KEY_OCTOPUS_URL, "https://www.baidu.com"); System.out.println("onSaveInstanceState(): Saved URL -> https://www.baidu.com"); } @Override protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // 提取之前保存的数据 String url = savedInstanceState.getString(KEY_OCTOPUS_URL); System.out.println("onRestoreInstanceState(): Restored URL -> " + url); } } ``` 此代码片段展示了如何利用 `onSaveInstanceState` 将字符串类型的 URL 地址存入 `Bundle`,以及如何分别在 `onCreate` 和 `onRestoreInstanceState` 中读取该值进行恢复操作[^1]。 #### 4. **常见问题及其解决方案** ##### (1)为什么有时不调用 `onSaveInstanceState`? 如果用户主动关闭应用程序(比如按下 Back 键),那么 `onSaveInstanceState` 不会被触发,因为它认为没有必要保留任何状态信息。 ##### (2)应该在哪里保存重要数据? 对于需要长期存储的重要数据,建议不要依赖于 `onSaveInstanceState`,而是考虑其他更可靠的方式,例如 SQLite 数据库、SharedPreferences 文件或者是远程服务器同步等手段[^3]。 ##### (3)如何判断是否发生了配置变化引起的重启而非完全退出再进入? 可以通过比较 Intent 是否相同或者设置标志位等方式区分这两种情形[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值