16

My Android application manages multiple fragments. I am seeing a large number of crashes in the field, however, containing this log line:

java.lang.IllegalStateException: Failure saving state: active XxxFragment{81e598 id=0x7f0b0069 tag_yyy} has cleared index: -1

Searches of answers in Stack Overflow have been fruitless; I seem to have a lot of company in wondering exactly what this exception means. Digging into the exception trace and Android sources, I can see that the exception is coming from the point at which my main Activity is saving its state (FragmentActivity.onSaveInstanceState), and the individual Fragments are being written into a Parcelable. Each Fragment has an index (called mIndex) which must be nonnegative, but it's not really clear from the code why that must be the case, as mIndex is never used again in that function.

I have no good idea how the Fragment gets into this state, or what I can do about it. I have been unable to reproduce the error in my own test environment. Can anyone shed any light on how to avoid and/or deal with this exception?

Related SO questions:

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

What does active fragment has cleared index: -1 mean and how do I fix it?

Getting exception as Failure saving state: active Fragment has cleared index: -1 when I am pressing home button of android device

IllegalStateException with Android Fragments

Community
  • 1
  • 1
Patrick Brennan
  • 2,688
  • 3
  • 20
  • 30
  • 1
    It's possible you're not properly managing fragment state when your app goes into the background (i.e. using the Home key for example) and is killed then restored later by Android when the user returns to it. You can simulate these conditions by going into Developer settings on the handset and enabling "Do not keep activities" and setting "Limit background processes" to "No background processes". Once you set those options, use your application and/or put it in the background with the Home key and open other apps, then return to it. – Marius Jan 29 '15 at 04:29
  • Good idea, but when I tried this I was still unable to duplicate the behavior. – Patrick Brennan Jan 30 '15 at 05:24
  • see my comment here: http://stackoverflow.com/questions/23631528/getting-exception-as-failure-saving-state-active-fragment-has-cleared-index-1 As I say there, I'm not sure why removing `setRetainInstance(true)` fixes the issue for me, but it's worth looking into if you're getting this error. – prodaea Apr 17 '15 at 15:23

2 Answers2

7

I'm going to redact my previous comment and make this an actual answer. setRetainInstance(true) was a red herring. At least in my case. Start here: http://www.localwisdom.com/blog/2013/03/android-error-java-lang-illegalstateexception-failure-saving-state-active-fragmentname/

"You most likely tried to perform a fragment transaction where you didn’t have reference to the correct instance of a fragment"

When I read that it all made sense for me. I was doing 2 wrong things with fragments.

  1. My offending fragments were singletons. (Major no-no)
  2. I was trying to use these same fragment instances across Activities without correctly saving state. (Which can be achieved by methods mentioned here: https://stackoverflow.com/a/12465343/333525)

(Hope this helps. It was too long for just a comment.)

Community
  • 1
  • 1
prodaea
  • 1,720
  • 1
  • 14
  • 20
  • 1
    Yes, when I stopped holding references to the fragments in question altogether - only getting references from the FragmentManager when I needed them, and then letting those references go out of scope as soon as possible - this problem went away for me. – Patrick Brennan Apr 30 '15 at 16:22
4

In my case I forgot to check is fragment was added before detaching and attaching it:

if (fragment != null && fragment.isAdded()) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .detach(fragment)
                    .attach(fragment)
                    .commit();
        }
Henadzi Rabkin
  • 6,834
  • 3
  • 32
  • 39