android:support:fragments saved by Activity is getting larger and causing TransactionTooLargeException

2.2k Views Asked by At

I have an Activity which controls several Fragments. The default Fragment is HomepageFragment. When replacing to a different Fragment i always make sure the stack stays flat - meaning only the HomepageFragment stays in the stack and on top of it the current Fragment. For example:

  1. Activity opened with HomepageFragment
  2. Replace to FragmentA is needed - all is good cause HomepageFragment is the last Fragment
  3. Now the stack is HomepageFragment -> FragmentA
  4. Replace to FragmentB is needed - first pop the last Fragment on the stack (fragmentA) than replace with FragmentB
  5. Now the stack is HomepageFragment -> FragmentB

On production i see many TransactionTooLargeException crashes.

I used TooLargeTool to track where the issue was coming from and I found out that as I switch between fragments in the activity there is a android:support:fragments key in the SaveInstanceState which is getting larger and larger (Exponentially) until the crash occurs.

It seems that even when popping from the stack, some data regarding the original transaction continues to be saved.

Removing it as suggest here is causing the Activity not to restore properly after being killed by th OS.

Is there something wrong with my method of flattening the stack? Is there a better approach? What data exactly is saved under android:support:fragments?

Note: I'm not setting any argument to those fragments. Also, thay save very small data in their saveInstanceState bundle.

Thanks!

1

There are 1 best solutions below

0
On

I did some debugging via supportFragmentManager.registerFragmentLifecycleCallbacks in my Activity, overriding and setting a breakpoint in onFragmentSaveInstanceState.

So it seems that the android:support:fragments Bundle includes

  1. Saved states from ViewModels (SavedStateHandle)
  2. Navigation args for Fragments on the back stack

In my case the culprit was a custom Parcelable that could grow to several hundreds of kB. With multiple of those on the back stack and in SavedStateHandles the app would cross the 1MB threshold and crash.

I solved the problem by passing just the ID for that Parcelable and loading it from my Repository. A slight hit on performance, but no more crashes.