rememberRetained
Remember the value produced by init.
It behaves similarly to remember, but the stored value will survive configuration changes, such as a screen rotation.
You can use it with a value stored inside mutableStateOf.
This differs from rememberSaveable
by not being tied to Android bundles or parcelable. You should take care to ensure that the state computed by init does not capture anything that is not safe to persist across reconfiguration, such as Navigators. The same caveats of rememberSaveable
also still apply (i.e. do not retain Android Contexts, Views, etc).
However, it does not participate in saved instance state either, so care should be taken to choose the right retention mechanism for your use case. Consider the below two examples.
The first case will retain state
across configuration changes and the back stack but will not survive process death.
@Composable
override fun present(): CounterState {
var state by rememberRetained { mutableStateOf(CounterState(0)) }
return CounterState(count) { event ->
when (event) {
is CounterEvent.Increment -> state = state.copy(count = state.count + 1)
is CounterEvent.Decrement -> state = state.copy(count = state.count - 1)
}
}
}
This second case will retain count
across configuration changes, the back stack, and survive process death. However, it only works with primitives or implicitly Saveable (i.e. Parcelable
on Android) state types.
@Composable
override fun present(): CounterState {
var count by rememberSaveable { mutableStateOf(0) }
return CounterState(count) { event ->
when (event) {
is CounterEvent.Increment -> state = count++
is CounterEvent.Decrement -> state = count--
}
}
}
Layering
There is also an overload of rememberRetained that takes a Saver, which participates in both the saved state registry system and retaining. Alternatively, use rememberRetainedSaveable for one that uses autoSaver. These can be used to persist state across multiple layers, allowing for both the caching of rememberRetained while also the process-death-survival of saveable.
Parameters
A set of inputs such that, when any of them have changed, will cause the state to reset and init to be rerun
An optional key to be used as a key for the saved value. If not provided we use the automatically generated by the Compose runtime which is unique for the every exact code location in the composition tree
A factory function to create the initial value of this state
Remember the value produced by init.
It behaves similarly to rememberRetained by retaining the value in memory, but with an additional saver parameter that will opportunistically save the value to saved instance state.
The retained value will be the source of truth for the value, except in the case where the process was killed, and the value is being restored. In that situation only, the most recent value recovered from the saveable state registry will be used instead of the value provided by init.
Importantly, the most recent value persisted in saveable state may lag behind the value that is saved in memory. For example, on Android, saved state will be collected when an Activity is backgrounded and onStop is called. The retained value might continue to be updated while in the background, but those updates will not be reflected in the saved state. If the process is killed before the app has returned to the foreground, these background updates will be lost, as the restored saved state will have been taken before the background updates occurred.
Therefore, saver should only store and restore information that is logically safe to have an out-of-date view of.
Parameters
A set of inputs such that, when any of them have changed, will cause the state to reset and init to be rerun
The Saver object which defines how the state is saved and restored.
An optional key to be used as a key for the saved value. If not provided we use the automatically generated by the Compose runtime which is unique for the every exact code location in the composition tree
A factory function to create the initial value of this state
Remember the value produced by init.
It behaves similarly to remember, but the stored value will survive configuration changes, such as a screen rotation.
Use this overload if you remember a mutable state to specify a stateSaver for the value contained inside the MutableState.
Parameters
A set of inputs such that, when any of them have changed, will cause the state to reset and init to be rerun
The Saver object which defines how the value inside the MutableState is saved and restored.
An optional key to be used as a key for the saved value. If not provided we use the automatically generated by the Compose runtime which is unique for the every exact code location in the composition tree
A factory function to create the initial value of this state