@@ -17,13 +17,16 @@ import androidx.lifecycle.Lifecycle.State
17
17
import androidx.lifecycle.Lifecycle.State.STARTED
18
18
import androidx.lifecycle.coroutineScope
19
19
import androidx.lifecycle.repeatOnLifecycle
20
+ import kotlinx.coroutines.CoroutineDispatcher
20
21
import kotlinx.coroutines.CoroutineScope
21
22
import kotlinx.coroutines.Dispatchers
22
23
import kotlinx.coroutines.Job
23
24
import kotlinx.coroutines.flow.Flow
24
25
import kotlinx.coroutines.flow.launchIn
25
26
import kotlinx.coroutines.flow.onEach
26
27
import kotlinx.coroutines.launch
28
+ import kotlin.coroutines.CoroutineContext
29
+ import kotlin.coroutines.EmptyCoroutineContext
27
30
28
31
/* *
29
32
* A view that can be driven by a stream of [Screen] renderings passed to its [take] method.
@@ -86,15 +89,26 @@ public class WorkflowLayout(
86
89
* Typically this comes from `ComponentActivity.lifecycle` or `Fragment.lifecycle`.
87
90
* @param [repeatOnLifecycle] the lifecycle state in which renderings should be actively
88
91
* updated. Defaults to STARTED, which is appropriate for Activity and Fragment.
92
+ * @param [collectionContext] additional [CoroutineContext] we want for the coroutine that is
93
+ * launched to collect the renderings. This should not override the [CoroutineDispatcher][kotlinx.coroutines.CoroutineDispatcher]
94
+ * but may include some other instrumentation elements.
89
95
*/
96
+ @OptIn(ExperimentalStdlibApi ::class )
90
97
public fun take (
91
98
lifecycle : Lifecycle ,
92
99
renderings : Flow <Screen >,
93
- repeatOnLifecycle : State = STARTED
100
+ repeatOnLifecycle : State = STARTED ,
101
+ collectionContext : CoroutineContext = EmptyCoroutineContext
94
102
) {
103
+ // We remove the dispatcher as we want to use what is provided by the lifecycle.coroutineScope.
104
+ val contextWithoutDispatcher = collectionContext.minusKey(CoroutineDispatcher .Key )
105
+ val lifecycleDispatcher = lifecycle.coroutineScope.coroutineContext[CoroutineDispatcher .Key ]
95
106
// Just like https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda
96
- lifecycle.coroutineScope.launch {
107
+ lifecycle.coroutineScope.launch(contextWithoutDispatcher) {
97
108
lifecycle.repeatOnLifecycle(repeatOnLifecycle) {
109
+ require(coroutineContext[CoroutineDispatcher .Key ] == lifecycleDispatcher) {
110
+ " Collection dispatch should happen on the lifecycle's dispatcher."
111
+ }
98
112
renderings.collect { show(it) }
99
113
}
100
114
}
0 commit comments