Nick Cardoso Nick Cardoso - 1 month ago 15
Android Question

FragmentManager is already executing transactions. When is it safe to initialise pager after commit?

I have an activity hosting two fragments. The activity starts off showing a loader while it loads an object. The loaded object is then passed to both fragments as arguments via newInstance methods and those fragments are attached.

final FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.container1, Fragment1.newInstance(loadedObject));
trans.replace(R.id.container2, Fragment2.newInstance(loadedObject));
trans.commit();


The second fragment contains a android.support.v4.view.ViewPager and tabs. onResume we initialise it like follows

viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(adapter.getCount()); //the count is always < 4
tabLayout.setupWithViewPager(viewPager);


The problem is android then throws


java.lang.IllegalStateException: FragmentManager is already executing
transactions


With this stack trace: (I took
android.support
out of the package names just for brevity)



v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1620)
at
v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:637)
at
v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
at v4.view.ViewPager.populate(ViewPager.java:1235)
at v4.view.ViewPager.populate(ViewPager.java:1083)
at
v4.view.ViewPager.setOffscreenPageLimit(ViewPager.java:847)


The data shows if
setOffscreenPageLimit(...);
is removed. Is there another way to avoid this issue?

When in the lifecycle is the fragment transaction complete so that I can wait to setup my pager?

Answer

If you're targeting sdk 24 and above you can use:

FragmentTransaction.commitNow()

instead of commit()

If you're targeting older versions, try calling:

FragmentManager.executePendingTransactions()

after the call to commit()