Queueing state changes and handling onPause() — Creating a Flow-like custom backstack (Part 3)

The original version of our Backstack

  • working goBack(), goTo(), setHistory() methods
  • initialization when we set the new stateChanger
  • a boolean flag that shows whether we are currently changing states or not, and we say IllegalStateException (or just return true; in case of goBack()) if there’s already one in progress
  • if the state change is asynchronous (for example has a ViewUtils.waitForMeasure(View, OnMeasuredCallback) call in it to support view animation), then it is possible to schedule multiple state changes at the same time
  • if the app is in background, but we receive an asynchronous callback/event after onPause() which would for example open a dialog, then we would crash with IllegalStateException: Cannot execute this action after onSaveInstanceState().
  • the ability to temporarily detach and re-attach our StateChanger, with the option to either initialize it, or just reattach it (without running the initializing state change)
  • the ability to queue the state changes when a StateChanger isn’t available, or is already executing a state change

Adding the ability to detach/reattach the StateChanger

Adding the ability to queue state changes

Reference reentrance tests

Reentrant Go

Reentrant Go Then Back

Reentrant Forward Then Go

Reentrance Wait For Callback

Calling state change completion callback twice should throw

Initializing state change (“bootstrap traversal”)

Pending traversal replaces bootstrap(!)

All pending traversals fire

Clearing dispatcher mid-traversal pauses

Handle state changer set in mid-flight waits for bootstrap(!)

Handle state changer set in mid-flight with big queue needs no bootstrap(!)

Traversals queued after dispatcher is removed then bootstrap the next one (!)

The final result

  • how to make sure you cannot have state changes after onPause()
  • handle queueing up StateChanges if a state change occurs during another active state change, or after onPause()



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Gabor Varadi

Gabor Varadi

Android dev. Zhuinden, or EpicPandaForce @ SO. Extension function fan #Kotlin, dislikes multiple Activities/Fragment backstack.