java.lang.IllegalStateException:失败保存状态:active已清除片段中的索引

时间:2013-09-30 15:25:32

标签: android android-fragments slidingmenu

首先,我的应用程序具有以下结构:

 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);
    }
}
你可以告诉我哪里错了吗?提前谢谢。

3 个答案:

答案 0 :(得分:1)

您的片段状态会自动保存并恢复,您无需在onSaveInstanceState方法中执行任何操作。不要在您的活动中提及您的片段的任何引用(在您的情况下为currentFragmentmContent),如果您需要某个片段,请通过例如FragmentManagerfindFragmentByTag获取。 ImageGroup

答案 1 :(得分:1)

在分离和附加之间读取片段状态可能存在问题。

尝试使用以下内容:

select 
    startpoints.id    gapstart, 
    min(endpoints.id) resume 
from (
     select id+1 id 
     from   yourtable outer_series 
     where not exists 
         (select null 
          from   yourtable inner_series 
          where  inner_series.id = outer_series.id + 1
         )
     order by id
     ) startpoints,   

     yourtable endpoints 
where 
    endpoints.id > startpoints.id 
group by 
    startpoints.id;

答案 2 :(得分:0)

尝试更改

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

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

我希望这有效