关于“IllegalStateException:在onSaveInstanceState之后无法执行此操作”有很多问题,但是当在显示片段以响应用户输入时引发此异常时,我找不到任何处理情况的内容即可。 (该应用仅适用于Android 4.0+。)
在我们读到的非常有启发性的article by Alex Lockwood中:
绝大多数应用程序只会在第一次调用onCreate()和/或响应用户输入时提交事务,而将永远不会遇到任何问题。
然而,这正是我所面对的(我认为)。根据堆栈跟踪,在用户单击Action Bar菜单项后会引发异常(非常偶然):
Thread: main, Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1265)
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1276)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
at android.app.BackStackRecord.commit(BackStackRecord.java:525)
at android.app.DialogFragment.show(DialogFragment.java:230)
at com.XXX.XXX.XXX.onOptionsItemSelected(SourceFile:XXX)
at android.app.Activity.onMenuItemSelected(Activity.java:2507)
at android.support.v4.app.g.onMenuItemSelected(SourceFile:372)
at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:979)
...
这是引发异常的方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.miAbout) {
final DialogFragment df = DialogAbout.newInstance();
//Here we have exception very occasionally:
df.show(getFragmentManager(), "about");
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
我知道我可以通过提交允许状态丢失的事务来避免异常:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.miAbout) {
final DialogFragment df = DialogAbout.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(df, null);
ft.commitAllowingStateLoss();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
但是,我仍然不明白为响应用户点击而引发异常的可能性如何。由于在onPause之后调用onSaveInstanceState(在后蜂窝中),这意味着该活动在暂停后仍会处理用户点击(这真是一个惊喜!)。或者也许用户点击会有一些延迟处理。理解这里发生的事情会很好。