【问题标题】:java.lang.IllegalStateException: Failure saving state: active has cleared index in fragmentjava.lang.IllegalStateException:失败保存状态:活动已清除片段中的索引
【发布时间】:2017-01-03 13:47:56
【问题描述】:

首先,我的应用具有这样的结构:

 SpashActivity -> MainActivity -> switching between many fragments

我的应用使用SlideMenu 在片段之间切换。我必须使用attach 而不是replace 来保持片段状态。它看起来像:

  public void switchContent(int index, String fragmentTag) {                
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    if (fragmentManager.findFragmentByTag(fragmentTag) != mContent) {
        if (!mContent.isDetached()) {
            transaction.detach(mContent);
        }
        if (null == fragmentManager.findFragmentByTag(fragmentTag)) {
            switch (index) {
            case 0:
                mContent = new CategoryFragment();
                break;
            case 1:
                mContent = new BookFragment();
                break;
            case 2:
                mContent = new BookDetailFragment();
                break;
             // etc
            }
        } else {
                mContent = fragmentManager.findFragmentByTag(fragmentTag);              
        }

        if (mContent.isDetached()) {
            transaction.attach(mContent);
        } else if (!mContent.isAdded()) {
            transaction.add(R.id.content_frame, mContent, fragmentTag);
        }

        transaction.addToBackStack(null);
        transaction.commit();
        fragmentManager.executePendingTransactions();
    }
    Handler h = new Handler();
    h.postDelayed(new Runnable() {
        public void run() {
            getSlidingMenu().showContent();
        }
    }, 50);
} 

当后台堆栈倒数为零时,我的应用程序必须退出:

 @Override
public void onBackPressed() {
    if (0 == getSupportFragmentManager().getBackStackEntryCount()) {
        // show confirm exit dialog.
        // If user press ok, try to exit, the splash activity will call finish()  
         // if(dialog == ok){ 
           Intent intent = new Intent(MainActivity.this, SplashActivity.class);
           intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
           intent.putExtra(SplashActivity.EXIT_KEY, true);
           startActivity(intent);
         // }  
    } else {
        super.onBackPressed();
    }
}

有时(并非总是如此)当用户多次按下返回时,我得到了异常并崩溃了我的应用程序(即使没有出现确认退出对话框 - 意味着返回堆栈计数大于零):

  09-30 20:32:53.419: E/AndroidRuntime(796): Uncaught handler: thread main exiting due to uncaught exception
  09-30 20:32:53.470: E/AndroidRuntime(796): java.lang.RuntimeException: Unable to pause activity {com.org.scgroup/com.org.scgroup.MainActivity}: java.lang.IllegalStateException: Failure saving state: active BookDetailFragment{43e7e0d8} has cleared index: -1
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3162)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3119)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3102)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.ActivityThread.access$2400(ActivityThread.java:119)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.os.Handler.dispatchMessage(Handler.java:99)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.os.Looper.loop(Looper.java:123)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.ActivityThread.main(ActivityThread.java:4363)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at java.lang.reflect.Method.invokeNative(Native Method)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at java.lang.reflect.Method.invoke(Method.java:521)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at dalvik.system.NativeStart.main(Native Method)
  09-30 20:32:53.470: E/AndroidRuntime(796): Caused by: java.lang.IllegalStateException: Failure saving state: active BookDetailFragment{43e7e0d8} has cleared index: -1
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1716)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:532)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at com.actionbarsherlock.app.SherlockFragmentActivity.onSaveInstanceState(SherlockFragmentActivity.java:126)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity.onSaveInstanceState(SlidingFragmentActivity.java:51)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at com.org.scgroup.MainActivity.onSaveInstanceState(MainActivity.java:324)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.Activity.performSaveInstanceState(Activity.java:1022)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1180)
  09-30 20:32:53.470: E/AndroidRuntime(796):    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3144)
  09-30 20:32:53.470: E/AndroidRuntime(796):    ... 12 more

onSaveInstanceState 方法:

  @Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    try {
        Ln.d("onSaveInstanceState");
        outState.putInt(CURRENT_FRAGMENT_KEY, currentFragment);

        if (0 < getSupportFragmentManager().getBackStackEntryCount()) {
            getSupportFragmentManager().putFragment(outState, "mContent", mContent);
        }
    } catch (Exception ex) {
        Ln.e(ex);
    }
}

你能告诉我哪里错了吗?提前致谢。

【问题讨论】:

  • 你找到解决这个问题的方法了吗?
  • 不,我只是弄清楚当我使用替换而不是分离和附加片段时,不会发生此错误。
  • 我不认为这是解决方案,在我的情况下,我也做了一个替换事务,但这个错误也结束了:/
  • 我也面临类似的问题。你有什么解决办法吗。 java.lang.IllegalStateException: 保存状态失败:活动片段已清除索引:-1 如果是,请发布解决方案。
  • 对不起,我仍然没有得到解决方案。查源码可以发现active fragment list中的fragment index为-1,但不知道根本原因grepcode.com/file/repository.grepcode.com/java/ext/…

标签: android android-fragments slidingmenu


【解决方案1】:

片段的状态会自动保存和恢复,不需要在你的onSaveInstanceState方法中做任何事情。不要在您的活动中保留对您的片段的任何引用(在您的情况下为currentFragmentmContent),如果您需要某个片段,请从FragmentManager 获取它,例如findFragmentByTag.

【讨论】:

    【解决方案2】:

    在分离和附加之间读取片段统计数据可能存在问题。

    尝试使用这样的东西:

    FragmentTransaction ft = fragmentManager.beginTransaction();
    
    //ft.detach(fragment).attach(fragment).commitAllowingStateLoss(); // crashing
    
    ft.replace(getView().getId(), fragment).commitAllowingStateLoss(); // not crashing
    

    【讨论】:

      【解决方案3】:

      尝试改变

       @Override
      public void onBackPressed() {
          if (0 == getSupportFragmentManager().getBackStackEntryCount()) {
      

       @Override
      public void onBackPressed() {
          if (getSupportFragmentManager().getBackStackEntryCount() < 1 ) {
      

      我希望这行得通

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-27
        • 1970-01-01
        相关资源
        最近更新 更多