FragmentTransaction 在 OnClick 中提交“IllegalStateException:在 onSaveInstanceState 之后无法执行此操作”
FragmentTransaction commit in OnClick “IllegalStateException: Can not perform this action after onSaveInstanceState”
我在市场上有一个应用程序,但出现以下异常:
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1343)
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1361)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:729)
at android.app.BackStackRecord.commit(BackStackRecord.java:705)
at com.mysupercoolapp.ui.fragments.ResultFragment.onItemClick(ResultFragment.java:139)
at android.widget.AdapterView.performItemClick(AdapterView.java:339)
at android.widget.AbsListView.performItemClick(AbsListView.java:1544)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3721)
at android.widget.AbsListView.run(AbsListView.java:5660)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6837)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
我已经阅读了有关此问题的大部分主题,但我不知道我的代码做错了什么。这不像我在 onResume 方法中替换片段。我也没有缓存 FragmentTransaction 实例。
当用户单击 ListView 中的项目时,我会替换 Fragment。
我的 Fragment 的代码流程如下
OnCreateView > 执行 AsyncTask 以从数据库加载一些项目 > onPostExecute 调用一个方法来为 ListView 设置适配器并添加一个 OnItemClickListener 因此当用户按下 ListView 中的项目时它会在其他片段。
这是它的代码:
@Override
protected void onPostExecute(ResultAdapter adapter) {
// post execute in AsyncTask
setListAdapter(adapter);
}
public void setListAdapter(final ResultAdapter adapter) {
if (adapter != null && isAdded()) {
resultList.setAdapter(adapter);
resultList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final FragmentTransaction ft = getFragmentManager().beginTransaction();
SomeFragment fragment = new SomeFragment();
ft.replace(R.id.content_frame, fragment, "main_fragment");
ft.addToBackStack(null);
ft.commit();
}
});
adapter.notifyDataSetChanged();
}
}
是否有比调用 commitAllowingStateLoss()
或覆盖 onSaveInstanceState()
更好的解决方案?
P.S.: 我的目标是 API > 14 并且我正在使用标准的 android.app.FragmentTransaction
包。
在最小化应用程序时调用onPostExecute()
,尤其是在调用activity的onSaveInstanceState()
方法后调用onPostExecute()
时,会出现此问题。
如果您担心状态丢失,那么我建议您在用户最小化应用程序时取消您的AsyncTask
(可能在onStop()
方法中)。然后在您的 onPostExecute()
中,仅当 AsyncTask
未被取消时才调用 setListAdapter(adapter)
。这将确保您不会在调用 onSaveInstanceState()
后结束设置适配器。
有关如何完成此操作的更多信息,请参见此处:
我在市场上有一个应用程序,但出现以下异常:
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1343)
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1361)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:729)
at android.app.BackStackRecord.commit(BackStackRecord.java:705)
at com.mysupercoolapp.ui.fragments.ResultFragment.onItemClick(ResultFragment.java:139)
at android.widget.AdapterView.performItemClick(AdapterView.java:339)
at android.widget.AbsListView.performItemClick(AbsListView.java:1544)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3721)
at android.widget.AbsListView.run(AbsListView.java:5660)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6837)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
我已经阅读了有关此问题的大部分主题,但我不知道我的代码做错了什么。这不像我在 onResume 方法中替换片段。我也没有缓存 FragmentTransaction 实例。 当用户单击 ListView 中的项目时,我会替换 Fragment。
我的 Fragment 的代码流程如下
OnCreateView > 执行 AsyncTask 以从数据库加载一些项目 > onPostExecute 调用一个方法来为 ListView 设置适配器并添加一个 OnItemClickListener 因此当用户按下 ListView 中的项目时它会在其他片段。
这是它的代码:
@Override
protected void onPostExecute(ResultAdapter adapter) {
// post execute in AsyncTask
setListAdapter(adapter);
}
public void setListAdapter(final ResultAdapter adapter) {
if (adapter != null && isAdded()) {
resultList.setAdapter(adapter);
resultList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final FragmentTransaction ft = getFragmentManager().beginTransaction();
SomeFragment fragment = new SomeFragment();
ft.replace(R.id.content_frame, fragment, "main_fragment");
ft.addToBackStack(null);
ft.commit();
}
});
adapter.notifyDataSetChanged();
}
}
是否有比调用 commitAllowingStateLoss()
或覆盖 onSaveInstanceState()
更好的解决方案?
P.S.: 我的目标是 API > 14 并且我正在使用标准的 android.app.FragmentTransaction
包。
在最小化应用程序时调用onPostExecute()
,尤其是在调用activity的onSaveInstanceState()
方法后调用onPostExecute()
时,会出现此问题。
如果您担心状态丢失,那么我建议您在用户最小化应用程序时取消您的AsyncTask
(可能在onStop()
方法中)。然后在您的 onPostExecute()
中,仅当 AsyncTask
未被取消时才调用 setListAdapter(adapter)
。这将确保您不会在调用 onSaveInstanceState()
后结束设置适配器。
有关如何完成此操作的更多信息,请参见此处: