有一个包含ID列表的列表片段。通过单击ID,新活动DETAIL_ACTIVITY将启动,并通过ID从其他服务加载数据。此加载发生在DETAIL_ACTIVITY的onResume方法中。加载完成后,获取的数据用于显示片段。像这样:
public void onResume(){
super.onResume();
fetchById(new Callback(){
public void success(Item someData){
SomeFragment fragment = ...
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment, fragment)
.commit();
}
});
}
大部分时间都可以使用。但是,当互联网连接速度很慢,并且当它尚未完成加载时我从DETAIL_ACTIVITY返回,它将抛出以下错误:
java.lang.IllegalStateException:之后无法执行此操作 的onSaveInstanceState 在android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1360) 在android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1378) 在android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) 在android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
使用
commitAllowingStateLoss()
无法解决此错误。关于这个的任何其他想法?
答案 0 :(得分:4)
即使我们解决了问题,接下来您将面临一个新的例外"活动已被销毁" ,因为您已从活动中退回。以下是抛出此异常的代码段。
private void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
}
}
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mActivity == null) {
throw new IllegalStateException("Activity has been destroyed");
}
...
}
对此的正确解决方法是,停止正在Activity
onPause方法中下载数据的主题,因为您已在{{3}中启动它方法。
来自onResume:
例如,如果您的活动有一个在后台运行的线程 要从网络下载数据,它可能会创建该线程 onCreate()然后在onDestroy()中停止线程。
取消运行改造目前不包含在库中。对于所有搜索解决方案,请参阅
答案 1 :(得分:1)
我打赌你已经解决了你的问题。但如果没有:
无法保证片段在FragmentActivity.onResume()
上恢复。根据Android开发人员文档,您应该在FragmentActivity.onResumeFragment()
中执行此操作。参见:
https://developer.android.com/reference/android/support/v4/app/FragmentActivity.html#onResume()
答案 2 :(得分:-1)
您是否尝试过不在onSaveInstanceState
中调用超级方法:
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
// No call to super.onSaveInstanceState
}
答案 3 :(得分:-1)
我认为您可以使用Handler重定向Thread的结果,然后再添加Fragment。因为线程在内存中运行单独的进程。所以请使用处理程序