# RetainedEffect

Common/All

## Functions summary

|---|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable @https://developer.android.com/reference/kotlin/androidx/compose/runtime/NonRestartableComposable [RetainedEffect](https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Function1))(effect: https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope.() -> https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectResult)` **This function is deprecated.** RetainedEffect must provide one or more 'key' parameters that define the identity of the RetainedEffect and determine when its previous effect should be disposed and a new effect started for the new key. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable @https://developer.android.com/reference/kotlin/androidx/compose/runtime/NonRestartableComposable https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)(key1: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?, effect: https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope.() -> https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectResult)` A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` permanently leaves composition. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable @https://developer.android.com/reference/kotlin/androidx/compose/runtime/NonRestartableComposable https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)(vararg keys: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?, effect: https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope.() -> https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectResult)` A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Array,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Array,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` permanently leaves composition. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable @https://developer.android.com/reference/kotlin/androidx/compose/runtime/NonRestartableComposable https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)(key1: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?, key2: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?, effect: https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope.() -> https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectResult)` A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` permanently leaves composition. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable @https://developer.android.com/reference/kotlin/androidx/compose/runtime/NonRestartableComposable https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)( key1: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?, key2: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?, key3: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?, effect: https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope.() -> https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectResult )` A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` permanently leaves composition. | Cmn |

## Functions

### RetainedEffect

Cmn Artifact: [androidx.compose.runtime:runtime-retain](https://developer.android.com/jetpack/androidx/releases/compose-runtime) [View Source](https://cs.android.com/search?q=file:androidx/compose/runtime/retain/RetainedEffect.kt+function:RetainedEffect)

```
@Composable
@NonRestartableComposable
fun [RetainedEffect](https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Function1))(effect: RetainedEffectScope.() -> RetainedEffectResult): Unit
```

> [!CAUTION]
> **This function is deprecated.**   
> RetainedEffect must provide one or more 'key' parameters that define the identity of the RetainedEffect and determine when its previous effect should be disposed and a new effect started for the new key.

### RetainedEffect

Cmn Artifact: [androidx.compose.runtime:runtime-retain](https://developer.android.com/jetpack/androidx/releases/compose-runtime) [View Source](https://cs.android.com/search?q=file:androidx/compose/runtime/retain/RetainedEffect.kt+function:RetainedEffect)

```
@Composable
@NonRestartableComposable
fun RetainedEffect(key1: Any?, effect: RetainedEffectScope.() -> RetainedEffectResult): Unit
```

A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` permanently leaves composition.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` tracks the lifecycle of retained content. If the current `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is retaining values because its managed content is being transiently destroyed, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` is kept alive. From this state, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` can either:

- Be retired because the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is destroyed without its content being restored

- Be retired if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore`'s content re-enters the composition but does not include this `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` or invokes it with different keys

- Be restored to the recreated composition hierarchy. In this case, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` does not execute any callbacks.

If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` is removed from the composition hierarchy when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is not retaining exited values, then the scope will immediately be retired and behave like a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/DisposableEffect.composable#DisposableEffect(kotlin.Function1)`. Retirement has the same timing guarantees as `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainObserver#onRetired()`.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)`'s *key* is a value that defines the identity of the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)`. If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` is recomposed with different keys, a new effect will be created and the previous effect will be retired. If the current RetainedValuesStore is not retaining exited values, the retirement happens before the new effect is started. Otherwise, the prior instance of the effect will continue to be retained for possible restoration until the scope stops retaining exited values.

`https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` may be used to initialize or subscribe to a key and reinitialize when a different key is provided. For example:

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.retain.RetainedEffect
import androidx.compose.runtime.retain.retain

@Composable
fun VideoPlayer(mediaUri: String) {
    val player = retain(mediaUri) { MediaPlayer(mediaUri) }

    // Initialize each player only once after we retain it.
    // If the uri (and therefore the player) change, we need to dispose the old player
    // and initialize the new one. Likewise, the player needs to be disposed of when
    // it stops being retained.
    RetainedEffect(player) {
        player.initialize()
        onRetire { player.close() }
    }

    // ...
}
```

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Function1)` **must** include a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` clause as the final statement in its `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Function1)` block. If your operation does not require disposal it might be a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/SideEffect.composable#SideEffect(kotlin.Function0)` instead, or a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/LaunchedEffect.composable#LaunchedEffect(kotlin.coroutines.SuspendFunction1)` if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` for every call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Function1)`. Both `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Function1)` and `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running `https://developer.android.com/reference/kotlin/androidx/compose/runtime/RememberObserver` event callbacks.

### RetainedEffect

Cmn Artifact: [androidx.compose.runtime:runtime-retain](https://developer.android.com/jetpack/androidx/releases/compose-runtime) [View Source](https://cs.android.com/search?q=file:androidx/compose/runtime/retain/RetainedEffect.kt+function:RetainedEffect)

```
@Composable
@NonRestartableComposable
fun RetainedEffect(vararg keys: Any?, effect: RetainedEffectScope.() -> RetainedEffectResult): Unit
```

A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Array,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Array,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` permanently leaves composition.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` tracks the lifecycle of retained content. If the current `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is retaining values because its managed content is being transiently destroyed, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` is kept alive. From this state, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` can either:

- Be retired because the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is destroyed without its content being restored

- Be retired if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore`'s content re-enters the composition but does not include this `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` or invokes it with different keys

- Be restored to the recreated composition hierarchy. In this case, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` does not execute any callbacks.

If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` is removed from the composition hierarchy when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is not retaining exited values, then the scope will immediately be retired and behave like a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)`. Retirement has the same timing guarantees as `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainObserver#onRetired()`.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)`'s *key* is a value that defines the identity of the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)`. If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` is recomposed with different keys, a new effect will be created and the previous effect will be retired. If the current RetainedValuesStore is not retaining exited values, the retirement happens before the new effect is started. Otherwise, the prior instance of the effect will continue to be retained for possible restoration until the scope stops retaining exited values.

`https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` may be used to initialize or subscribe to a key and reinitialize when a different key is provided. For example:

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.retain.RetainedEffect
import androidx.compose.runtime.retain.retain

@Composable
fun VideoPlayer(mediaUri: String) {
    val player = retain(mediaUri) { MediaPlayer(mediaUri) }

    // Initialize each player only once after we retain it.
    // If the uri (and therefore the player) change, we need to dispose the old player
    // and initialize the new one. Likewise, the player needs to be disposed of when
    // it stops being retained.
    RetainedEffect(player) {
        player.initialize()
        onRetire { player.close() }
    }

    // ...
}
```

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Array,kotlin.Function1)` **must** include a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` clause as the final statement in its `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Array,kotlin.Function1)` block. If your operation does not require disposal it might be a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/SideEffect.composable#SideEffect(kotlin.Function0)` instead, or a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/LaunchedEffect.composable#LaunchedEffect(kotlin.coroutines.SuspendFunction1)` if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` for every call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Array,kotlin.Function1)`. Both `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Array,kotlin.Function1)` and `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running `https://developer.android.com/reference/kotlin/androidx/compose/runtime/RememberObserver` event callbacks.

### RetainedEffect

Cmn Artifact: [androidx.compose.runtime:runtime-retain](https://developer.android.com/jetpack/androidx/releases/compose-runtime) [View Source](https://cs.android.com/search?q=file:androidx/compose/runtime/retain/RetainedEffect.kt+function:RetainedEffect)

```
@Composable
@NonRestartableComposable
fun RetainedEffect(key1: Any?, key2: Any?, effect: RetainedEffectScope.() -> RetainedEffectResult): Unit
```

A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` permanently leaves composition.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` tracks the lifecycle of retained content. If the current `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is retaining values because its managed content is being transiently destroyed, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` is kept alive. From this state, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` can either:

- Be retired because the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is destroyed without its content being restored

- Be retired if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore`'s content re-enters the composition but does not include this `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` or invokes it with different keys

- Be restored to the recreated composition hierarchy. In this case, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` does not execute any callbacks.

If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` is removed from the composition hierarchy when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is not retaining exited values, then the scope will immediately be retired and behave like a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/DisposableEffect.composable#DisposableEffect(kotlin.Function1)`. Retirement has the same timing guarantees as `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainObserver#onRetired()`.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)`'s *key* is a value that defines the identity of the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)`. If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` is recomposed with different keys, a new effect will be created and the previous effect will be retired. If the current RetainedValuesStore is not retaining exited values, the retirement happens before the new effect is started. Otherwise, the prior instance of the effect will continue to be retained for possible restoration until the scope stops retaining exited values.

`https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` may be used to initialize or subscribe to a key and reinitialize when a different key is provided. For example:

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.retain.RetainedEffect
import androidx.compose.runtime.retain.retain

@Composable
fun VideoPlayer(mediaUri: String) {
    val player = retain(mediaUri) { MediaPlayer(mediaUri) }

    // Initialize each player only once after we retain it.
    // If the uri (and therefore the player) change, we need to dispose the old player
    // and initialize the new one. Likewise, the player needs to be disposed of when
    // it stops being retained.
    RetainedEffect(player) {
        player.initialize()
        onRetire { player.close() }
    }

    // ...
}
```

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` **must** include a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` clause as the final statement in its `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` block. If your operation does not require disposal it might be a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/SideEffect.composable#SideEffect(kotlin.Function0)` instead, or a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/LaunchedEffect.composable#LaunchedEffect(kotlin.coroutines.SuspendFunction1)` if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` for every call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)`. Both `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Function1)` and `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running `https://developer.android.com/reference/kotlin/androidx/compose/runtime/RememberObserver` event callbacks.

### RetainedEffect

Cmn Artifact: [androidx.compose.runtime:runtime-retain](https://developer.android.com/jetpack/androidx/releases/compose-runtime) [View Source](https://cs.android.com/search?q=file:androidx/compose/runtime/retain/RetainedEffect.kt+function:RetainedEffect)

```
@Composable
@NonRestartableComposable
fun RetainedEffect(
    key1: Any?,
    key2: Any?,
    key3: Any?,
    effect: RetainedEffectScope.() -> RetainedEffectResult
): Unit
```

A side effect of composition that must run for any new unique value of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` and must be reversed or cleaned up if `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`, or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` changes or if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` permanently leaves composition.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` tracks the lifecycle of retained content. If the current `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is retaining values because its managed content is being transiently destroyed, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` is kept alive. From this state, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` can either:

- Be retired because the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is destroyed without its content being restored

- Be retired if the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore`'s content re-enters the composition but does not include this `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` or invokes it with different keys

- Be restored to the recreated composition hierarchy. In this case, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` does not execute any callbacks.

If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` is removed from the composition hierarchy when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedValuesStore` is not retaining exited values, then the scope will immediately be retired and behave like a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/DisposableEffect.composable#DisposableEffect(kotlin.Function1)`. Retirement has the same timing guarantees as `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainObserver#onRetired()`.

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`'s *key* is a value that defines the identity of the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`. If a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` is recomposed with different keys, a new effect will be created and the previous effect will be retired. If the current RetainedValuesStore is not retaining exited values, the retirement happens before the new effect is started. Otherwise, the prior instance of the effect will continue to be retained for possible restoration until the scope stops retaining exited values.

`https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` may be used to initialize or subscribe to a key and reinitialize when a different key is provided. For example:

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.retain.RetainedEffect
import androidx.compose.runtime.retain.retain

@Composable
fun VideoPlayer(mediaUri: String) {
    val player = retain(mediaUri) { MediaPlayer(mediaUri) }

    // Initialize each player only once after we retain it.
    // If the uri (and therefore the player) change, we need to dispose the old player
    // and initialize the new one. Likewise, the player needs to be disposed of when
    // it stops being retained.
    RetainedEffect(player) {
        player.initialize()
        onRetire { player.close() }
    }

    // ...
}
```

A `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffect.composable#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` **must** include a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` clause as the final statement in its `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` block. If your operation does not require disposal it might be a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/SideEffect.composable#SideEffect(kotlin.Function0)` instead, or a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/LaunchedEffect.composable#LaunchedEffect(kotlin.coroutines.SuspendFunction1)` if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` for every call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)`. Both `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/package-summary#RetainedEffect(kotlin.Any,kotlin.Any,kotlin.Any,kotlin.Function1)` and `https://developer.android.com/reference/kotlin/androidx/compose/runtime/retain/RetainedEffectScope#onRetire(kotlin.Function0)` will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running `https://developer.android.com/reference/kotlin/androidx/compose/runtime/RememberObserver` event callbacks.