java.lang.IllegalStateException: Failure saving state: active has cleared index in fragment

柔情痞子 提交于 2019-12-13 11:38:56

问题


First, my app has structure like this:

 SpashActivity -> MainActivity -> switching between many fragments

My app use SlideMenu to switch between fragments. I have to use attach instead of replace to keep fragment state. It's look like:

  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);
} 

When the back stack count down to zero, my app has to exit:

 @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();
    }
}

But sometimes (not always) I got the exception and crash my app when user press back many times (even the confirm exit dialog not appear - mean back stack count greater than zero):

  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

The onSaveInstanceState method:

  @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);
    }
}

Could you please tell me where I am wrong? Thanks in advance.


回答1:


The state of your fragments is automatically saved and restored, there is no need to do anything in your onSaveInstanceState method. Don't hold any references to your Fragments in your Activity (in your case currentFragment, mContent), if you need a certain Fragment, get it from FragmentManager by e.g. findFragmentByTag.




回答2:


Possible problem with reading fragment stat between detach and attach.

Try to use something like this:

FragmentTransaction ft = fragmentManager.beginTransaction();

//ft.detach(fragment).attach(fragment).commitAllowingStateLoss(); // crashing

ft.replace(getView().getId(), fragment).commitAllowingStateLoss(); // not crashing



回答3:


Try to change

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

to

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

I hope this works



来源:https://stackoverflow.com/questions/19098026/java-lang-illegalstateexception-failure-saving-state-active-has-cleared-index

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!