RetainedValuesStore

Known direct subclasses
ControlledRetainedValuesStore

A ControlledRetainedValuesStore is effectively a "Mutable" RetainedValuesStore.

ForgetfulRetainedValuesStore

The ForgetfulRetainedValuesStore is an implementation of RetainedValuesStore that is incapable of retaining any exited values.


A RetainedValuesStore acts as a storage area for objects being retained. An instance of a RetainedValuesStore also defines a specific retention policy to describe when removed retained values should be kept for future reuse and when they should be retired.

The general pattern for retention is as follows:

  1. The RetainedValuesStore receives a notification that transient content removal is about to begin. The source of this notification varies depending on what retention scenario is being captured, but could, for example, be a signal that an Android Activity is being recreated, or that content is about to be navigated away from/collapsed with the potential of being returned to. At this time, the store's owner should call requestRetainExitedValues.

  2. Transient content removal begins. The content is recomposed, removed from the hierarchy, and remembered values are forgotten. Values remembered by retain leave the composition but are not yet released. Every value returned by retain will be passed as an argument to saveExitingValue so that it can later be returned by getExitedValueOrDefault.

  3. An arbitrary amount of time passes, and the removed content is restored in the composition hierarchy at its previous location. When a retain call is invoked during the restoration, it calls getExitedValueOrDefault. If all the input keys match a retained value, the previous result is returned and the retained value is removed from the pool of restorable objects that exited the previous composition. This step may be skipped if it becomes impossible to return to the transiently removed content while this store is retaining exited values.

  4. The content finishes composing after being restored, and the entire frame completes. The owner of this store should call unRequestRetainExitedValues. When retention stops being requested, it immediately ends. Any values that are retained and not currently used in a composition (and therefore not restored by getExitedValueOrDefault) are then immediately discarded.

A given RetainedValuesStore should only be used by a single Recomposer at a time. It can move between recomposers (for example, when the Window is recreated), but should never be used by two Recomposers simultaneously. It is valid for a RetainedValuesStore to be used in multiple compositions at the same time, or in the same composition multiple times.

Summary

Public constructors

Cmn

Public functions

final Unit

Registers the given observer with this RetainStateProvider to be notified when the value of isRetainingExitedValues changes.

Cmn
abstract Any?
getExitedValueOrElse(key: Any, defaultValue: Any?)

If this store is currently retaining exited values and has a value previously created with the given key, its original record is returned and removed from the list of exited kept objects that this store is tracking.

Cmn
final Unit

Removes a previously registered observer.

Cmn

Protected functions

abstract Unit

Called when this store first starts to retain exited values (i.e. when isRetainingExitedValues transitions from false to true).

Cmn
abstract Unit

Called when this store stops retaining exited values (i.e. when isRetainingExitedValues transitions from true to false).

Cmn
Unit

Called to increment the number of requests to retain exited values.

Cmn
abstract Unit
saveExitingValue(key: Any, value: Any?)

Invoked when a retained value is exiting composition while this store is retaining exited values.

Cmn
Unit

Clears a previous call to requestRetainExitedValues.

Cmn

Public properties

final Boolean

Returns whether retained values should continue to be held when they are removed from the composition hierarchy.

Cmn

Protected properties

Int
Cmn

Public constructors

RetainedValuesStore

RetainedValuesStore()

Public functions

addRetainStateObserver

final fun addRetainStateObserver(
    observer: RetainStateProvider.RetainStateObserver
): Unit

Registers the given observer with this RetainStateProvider to be notified when the value of isRetainingExitedValues changes. The added observer will receive its first notification the next time isRetainingExitedValues is updated.

This method is not thread safe and should only be invoked on the applier thread.

getExitedValueOrElse

abstract fun getExitedValueOrElse(key: Any, defaultValue: Any?): Any?

If this store is currently retaining exited values and has a value previously created with the given key, its original record is returned and removed from the list of exited kept objects that this store is tracking.

Parameters
key: Any

The keys to resolve a retained value that has left composition

defaultValue: Any?

A value to be returned if there are no retained values that have exited composition and are being held by this RetainedValuesStore for the given key.

Returns
Any?

A retained value for key if there is one and it hasn't already re-entered composition, otherwise defaultValue.

removeRetainStateObserver

final fun removeRetainStateObserver(
    observer: RetainStateProvider.RetainStateObserver
): Unit

Removes a previously registered observer. It will receive no further updates from this RetainStateProvider unless it is registered again in the future. If the observer is not currently registered, this this method does nothing.

This method is not thread safe and should only be invoked on the applier thread.

Protected functions

onStartRetainingExitedValues

protected abstract fun onStartRetainingExitedValues(): Unit

Called when this store first starts to retain exited values (i.e. when isRetainingExitedValues transitions from false to true). When this is called, implementors should prepare to begin to store values they receive from saveExitingValue.

onStopRetainingExitedValues

protected abstract fun onStopRetainingExitedValues(): Unit

Called when this store stops retaining exited values (i.e. when isRetainingExitedValues transitions from true to false). After this is called, all exited values that have been kept and not restored via getExitedValueOrElse should be retired.

Implementors MUST invoke RetainObserver.onRetired for all exited and unrestored RememberObservers when this method is invoked.

requestRetainExitedValues

protected fun requestRetainExitedValues(): Unit

Called to increment the number of requests to retain exited values. When there are a positive number of requests, this store begins retaining exited values and continues until all requests are cleared.

This method is not thread safe and should only be called on the applier thread.

saveExitingValue

protected abstract fun saveExitingValue(key: Any, value: Any?): Unit

Invoked when a retained value is exiting composition while this store is retaining exited values. It is up to the implementation of this method to decide whether and how to store these values so that they can later be retrieved by getExitedValueOrElse.

The given key are not guaranteed to be unique. To handle duplicate keys, implementors should return retained values with the same keys from getExitedValueOrElse in the opposite order they are received by saveExitingValue.

If the implementation of this store does not accept this value into its kept exited object list, it MUST call RetainObserver.onRetired if value implements RetainObserver.

unRequestRetainExitedValues

protected fun unRequestRetainExitedValues(): Unit

Clears a previous call to requestRetainExitedValues. If all requests to retain exited values have been cleared, this store will stop retaining exited values.

This method is not thread safe and should only be called on the applier thread.

Throws
kotlin.IllegalStateException

if unRequestRetainExitedValues is called more times than requestRetainExitedValues has been called.

Public properties

isRetainingExitedValues

final val isRetainingExitedValuesBoolean

Returns whether retained values should continue to be held when they are removed from the composition hierarchy. This indicates that content is being destroyed transiently and that the associated retention scenario of this RetainStateProvider (e.g. navigation moving a screen to the back stack, activity recreation, hidden UI, etc.) is currently active.

When true, associated RetainedValuesStores should continue to retain objects as they are removed from the composition hierarchy for future reuse.

Protected properties

retainExitedValuesRequests

protected val retainExitedValuesRequestsInt