onResume中的Commit片段导致IllegalStateException

时间:2014-08-13 08:08:40

标签: android android-fragments

有一个包含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()

无法解决此错误。关于这个的任何其他想法?

4 个答案:

答案 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。因为线程在内存中运行单独的进程。所以请使用处理程序