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:
- Activity opened with
HomepageFragment - Replace to
FragmentAis needed - all is good causeHomepageFragmentis the last Fragment - Now the stack is
HomepageFragment->FragmentA - Replace to
FragmentBis needed - first pop the last Fragment on the stack (fragmentA) than replace withFragmentB - 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!
I did some debugging via
supportFragmentManager.registerFragmentLifecycleCallbacksin my Activity, overriding and setting a breakpoint inonFragmentSaveInstanceState.So it seems that the
android:support:fragmentsBundle includesIn 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.