user1025013
user1025013

Reputation: 123

Fragment IllegalStateException - commit() causing state loss

I have a FragmentStatePagerAdapter that shows 3 tabs and of which, the 1st tab (fragment) commits a FragmentTransaction inside it's onCreateView(). For some users, I am seeing an IllegalStateException which is caused by commit() state loss.

After reading up on a few stack overflow Q&As and a blog post by Alex Lockwood on Fragment Transactions and Activity State Loss, I better understand what is causing the state loss and I can take several approaches.

  1. I can move my fragment commit to onPostResume.
  2. I can move my fragment commit to onCreate() - probably safest.

However, there is a lot of logic inside onCreateView() and if I were to take the above approach, I may introduce regression bugs. I am wondering, since onCreate() will eventually call onCreateView(), if it is okay to just check savedInstanceState for null. Would this solve the problem?

Here is my current code:

@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    FFragment frag = new FFragment();
    frag.setDateSelected(mDateSelected);
    getFragmentManager().beginTransaction()
            .add(R.id.container, frag, FRAG_TAG)
            .commit();
    ...
}

What I imagine would fix the state loss:

@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    if(savedInstanceState == null) {
        frag = new FFragment();
        frag.setDateSelected(mDateSelected);
        getFragmentManager().beginTransaction()
                .add(R.id.container, frag, FRAG_TAG)
                .commit();
    } else {
        frag = (FFragment) getSupportFragmentManager()
            .findFragmentByTag(FRAG_TAG);
    }
    ...
}

Why am I asking this and not just implementing and testing it? I've tried to kill the activity through ADB and DDMS but was not able to reproduce the state loss - thus asking if this approach would work. Or, do I have to do the inevitable and move the commit to onCreate or onPostResume()?

Is there another way to test trigger state loss?

Upvotes: 1

Views: 244

Answers (1)

Suhaib Roomy
Suhaib Roomy

Reputation: 2600

There are a couple of things you got wrong

  1. You are using getFragmentManager() and getSupportFragmentManager() inside a fragment, you should alwasy use getChildFragmentManager() when using nested fragments

  2. OnResumeFragments() and onCreate that Alex talked about are in respect to activity and not fragments, there is not such method inside a framgent

  3. The solution you are proposing is for an entirely different thing, it is used when the activity is recreated from the backstack

The solution would be to move your code to onViewCreated() method of your fragment and use childFragmentManager, I am using a viewpager inside a fragment and I initialize it inside onViewCreated(), haven't faced any such problem till now

Upvotes: 1

Related Questions