Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onViewCreated - wrong place to replace fragment?

I'm showing an empty fragment if the user has no data. In that emptyFragment (in onViewCreated) I check for a condition and sometimes would like to replace that empty Fragment with another one, so I call a method on the according activity which replaced the fragment.

Some users (currently only Samsung, 6.0.1 but I don't know if that means anything) experience a crash on the line where I executePendingTransactions:

IllegalStateException:

Fatal Exception: java.lang.RuntimeException
Unable to resume activity
{....app.activities.MyActivity_}:
java.lang.IllegalStateException: FragmentManager is already executing transactions

Is this a bug in 6.0.1 or is onViewCreated the wrong place to do this?

EDIT

Would this be a possible solution?

    if (addToBackStack) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, contentFragment, name).addToBackStack(name).commitAllowingStateLoss();
        getSupportFragmentManager().executePendingTransactions();
    } else {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, contentFragment, name).commitNow();
    }
like image 857
swalkner Avatar asked Nov 13 '16 08:11

swalkner


1 Answers

First of all: why don't you move the 'check condition' in your activity? In this way, you can decide what is the Fragment that you need: the one that manages empty values or the other one.

Second: I suggest to read two small tutorials about fragments commit and state loss. You can find many error conditions related to fragments there.

And finally the answer related to 'FragmentManager is already executing transactions': there are at least two nested calls to the executePendingTransactions() method, that means that you're asking to the fragment manager (there is a single instance of fragment manager per Activity) to execute a transaction while it's executing another transaction. It's hard to identify where is the issue, you should post all the code of the Activity and all involved Fragments, just to identify and remove one (the first one) call to executePendingTransactions, but I can give you some tips:

  1. Do not use executePendingTransactions(). It's hard to mantain a code that requires a sort of orchestration between fragments
  2. Use commit() if you don't need an immediate access to the fragments you're adding to your Activity. The simple commit will execute all transactions as soon as the main thread is free.
  3. If you need an immediate access to a fragment, use commitNow(). Honestly I've used this method just few times, mainly to correctly handle DialogFragments.

commitNow() is available for pre 24 devices if you use the support library, that I suggest you to adopt.

like image 169
Mimmo Grottoli Avatar answered Sep 27 '22 17:09

Mimmo Grottoli