Hello, people from Flutter made an extensive docum...
# compose
l
Hello, people from Flutter made an extensive document about state restoration and their plans (since it's not supported natively yet). When it comes to Jetpack Compose, I've not seen much about facilities to ease state saving (yet), so I'm wondering if that document could help shape the APIs that we can use to support state restoration easily. Here it is: https://flutter.dev/go/state-restoration-design
πŸ‘ 2
z
Compose supports state restoration via the
savedInstanceState
function - what else do you need?
l
An example with text input, a slider, and a list.
z
Just take any existing example that uses
state
and replace
state
with
savedInstanceState
.
l
I think I now see how it'd work, interesting
z
I think
RestorationManager
in this doc roughly corresponds to
UiSavedStateRegistry
,
RestorationId
to whatever key is used for
savedInstanceState
(the positional memoization key by default), and
RestorationScope
to the ambient that holds the
UiSavedStateRegistry
.
a
One other thing we've talked about doing not just for saved state but for other types of stable composition scope keying is some sort of
Path("key") { }
nesting that I think roughly parallels the nested bucket approach described here
πŸ‘ 3
This sort of thing also ends up being useful for things like activity result launchers via the new activity result jetpack lib
In particular the ability to get a developer-specified yet incrementally built identifier and use the composition key for the last mile means a ton of structure above the last explicit path marker can change for different configurations, etc.
πŸ™Œ 2
l
Something that'd really like is to be able to swap system savedInstance state by a custom alternative, very easily, that could then send those values over, for something like Handoff on iOS & macOS. That could also be used to sync reading position or alike, and have some state persist when coming back.
a
Interesting, I could see that falling out of some natural interface layering we'd want anyway for testing/etc.
πŸŽ‰ 1
So far though we've been leaning towards state restoration as being an initial value thing and not something that happens later and requires developers to perform a merge
Waiting for a cloud sync to potentially time out seems like a big hurdle to that, and the merging requirement sounds like it could introduce a lot of complexity for developers who don't need or want it
What do you think?
z
The Handoff use case seems like you could do with a custom function similar to
savedInstanceState
. You'd have to explicitly call that function instead of magically swapping it in, but it seems like the behavior would be different enough anyway (what Adam said, two way syncing?, Etc) that the opt-in would be safer.
@Adam Powell is there a way to subscribe to state changes on a
State
from non-compose code yet? Once that's available, you could build something like this on top of that with some coroutines and something like Store.
l
I was thinking there'd be two things: 1. Configuration and initialization of the
savedInstanceState
substitute (which might involve a suspending logic, and "linking" to an error handling logic) 2. Explicitedness about the actual key use for saving some data, to allow long term storage (i.e. not limited to the app version), without conflicts For merging, I was thinking it'd be something to handle in the logic of the
savedInstanceState
substitude.
a
@Zach Klippenstein (he/him) [MOD] There always has been but it's been pretty raw to use. This just went in and should make it easier https://android-review.googlesource.com/c/platform/frameworks/support/+/1326201
πŸ™Œ 2
@louiscad that would probably work πŸ™‚ another good reason for the generalized key path mechanism.
πŸ‘ 1
Even if you didn't use the last mile automatic keys from compose for stability
a
and yes, you can provide your own
UiSavedStateRegistry
with an ambient where you can do your own saving and restoration as it is nicely abstracted
πŸ‘Œ 1
l
Are there composables from androidx.ui or other first party lib(s) that already use
UiSavedStateRegistry
?
Bonus question: Can we trigger state saving manually?
a
yes, text fields and scrollers are saving the state already
and yes, you can gather the registry using an ambient and call performSave() on it
l
Thank you very much for your answers, I think I'll experiment with persisting state periodically later this summer (but not do I/O on the main thread ⏸️ )
z
I’ve got a proof-of-concept project that uses the saved state registry manually: https://github.com/zach-klippenstein/compose-backstack/blob/5fe89af17b9dc48ee28bea3e95c020ce353ff31b/compose-backstack/src/main/java/com/zachklipp/compose/backstack/ChildSavedStateRegistry.kt (thanks to @grandstaish for fixing my bugs πŸ˜…)
πŸ‘€ 1
πŸ‘πŸΌ 1