onViewCreated - wrong place to replace fragment?
Asked Answered
Z

2

10

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();
    }
Zoomorphism answered 13/11, 2016 at 8:55 Comment(1)
I had the same Exception "FragmentManager is already executing transactions" when did replaceFragment() synchronously in Fragment.onResume(). Is was floating exception.Discrepancy
B
5

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.

Botsford answered 16/11, 2016 at 22:30 Comment(3)
regarding first of all: because first I show a no-data-fragment, then, when the network call returns, I'd like to replace it with another one...Zoomorphism
Did you try to remove the executePendingTransaction?Botsford
I was just suggesting to keep your code and simply remove all calls to executePendingTransactionBotsford
E
0

Try FragmentTransaction.commitNow(); if you're dealing with sdk 24, instead of using commit()

For older versions: FragmentManager.executePendingTransactions() after the call of commit()

Elysium answered 15/11, 2016 at 10:27 Comment(1)
I AM using executePendingTransactions()Zoomorphism

© 2022 - 2024 — McMap. All rights reserved.