Skip to content

Commit 0b62bcc

Browse files
committed
ensure to keep a singule compose lifecycle owner and attach new parent lifecycles if new ones are provided
1 parent bf97796 commit 0b62bcc

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/ComposeLifecycleOwner.kt

+22-7
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ import androidx.lifecycle.LifecycleRegistry
1818
@Composable internal fun rememberChildLifecycleOwner(
1919
parentLifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle
2020
): LifecycleOwner {
21-
val lifecycleOwner = remember {
22-
ComposeLifecycleOwner.installOn(parentLifecycle)
21+
val owner = remember {
22+
ComposeLifecycleOwner.installOn(
23+
initialParentLifecycle = parentLifecycle
24+
)
25+
}
26+
val lifecycleOwner = remember(parentLifecycle) {
27+
owner.apply { updateParentLifecycle(parentLifecycle) }
2328
}
2429
return lifecycleOwner
2530
}
@@ -53,12 +58,16 @@ import androidx.lifecycle.LifecycleRegistry
5358
* - By integrating with Compose's lifecycle, it ensures that resources are properly released when
5459
* the composable leaves the composition.
5560
*
56-
* @param parentLifecycle The parent [Lifecycle] with which this lifecycle owner should synchronize.
61+
* @param initialParentLifecycle The parent [Lifecycle] with which this lifecycle owner should
62+
* synchronize with initially. If new parent lifecycles are provided, they should be passed to
63+
* [updateParentLifecycle].
5764
*/
5865
private class ComposeLifecycleOwner(
59-
private val parentLifecycle: Lifecycle
66+
initialParentLifecycle: Lifecycle
6067
) : LifecycleOwner, RememberObserver, LifecycleEventObserver {
6168

69+
private var parentLifecycle: Lifecycle = initialParentLifecycle
70+
6271
private val registry = LifecycleRegistry(this)
6372
override val lifecycle: Lifecycle
6473
get() = registry
@@ -79,6 +88,12 @@ private class ComposeLifecycleOwner(
7988
}
8089
}
8190

91+
fun updateParentLifecycle(lifecycle: Lifecycle) {
92+
parentLifecycle.removeObserver(this)
93+
parentLifecycle = lifecycle
94+
parentLifecycle.addObserver(this)
95+
}
96+
8297
override fun onStateChanged(
8398
source: LifecycleOwner,
8499
event: Event
@@ -87,16 +102,16 @@ private class ComposeLifecycleOwner(
87102
}
88103

89104
companion object {
90-
fun installOn(parentLifecycle: Lifecycle): ComposeLifecycleOwner {
91-
return ComposeLifecycleOwner(parentLifecycle).also {
105+
fun installOn(initialParentLifecycle: Lifecycle): ComposeLifecycleOwner {
106+
return ComposeLifecycleOwner(initialParentLifecycle).also {
92107
// We need to synchronize the lifecycles before the child ever even sees the lifecycle
93108
// because composes contract tries to guarantee that the lifecycle is in at least the
94109
// CREATED state by the time composition is actually running. If we don't synchronize
95110
// the lifecycles right away, then we break that invariant. One concrete case of this is
96111
// that SavedStateRegistry requires its lifecycle to be CREATED before reading values
97112
// from it, and consuming values from an SSR is a valid thing to do from composition
98113
// directly, and in fact AndroidComposeView itself does this.
99-
parentLifecycle.addObserver(it)
114+
initialParentLifecycle.addObserver(it)
100115
}
101116
}
102117
}

0 commit comments

Comments
 (0)