Taking the direct example from https://kotlinlang.org/docs/reference/coroutines/flow.html#flows-are-cold
fun simple(): Flow<Int> = flow { println("Flow started") for (i in 1..3) { delay(100) emit(i) } } fun main() = runBlocking<Unit> { println("Calling simple function...") val flow = simple() println("Calling collect...") flow.collect { value -> println(value) } println("Calling collect again...") flow.collect { value -> println(value) } }
I got the error on collect
.
This is an internal kotlinx.coroutines API that should not be used from outside of kotlinx.coroutines. No compatibility guarantees are provided.It is recommended to report your use-case of internal API to kotlinx.coroutines issue tracker, so stable API could be provided instead
When I add @InternalCoroutinesApi
@InternalCoroutinesApi fun main() = runBlocking<Unit> { println("Calling simple function...") val flow = simple() println("Calling collect...") flow.collect { value -> println(value) } println("Calling collect again...") flow.collect { value -> println(value) } }
I get an error in the collect
's lambda (function of value -> println(value
) as below
Type mismatch. Required: FlowCollector<Int> Found: ([ERROR : ]) → Unit Cannot infer a type for this parameter. Please specify it explicitly.
I am using Kotlin version 1.4.21.
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.2" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
Did I do anything wrong that I cannot compile the example code in Android Studio?
Flow is an idiomatic way in kotlin to publish sequence of values. While the flow itself suspendable, the collector will block the coroutine from proceeding further.
ExperimentalCoroutinesApiMarks declarations that are still experimental in coroutines API, which means that the design of the corresponding declarations has open issues which may (or may not) lead to their changes in the future.
Flows are built on top of coroutines and can provide multiple values. A flow is conceptually a stream of data that can be computed asynchronously. The emitted values must be of the same type.
Cold flow is what you need if the flow needs a collector. Each collector has its own instance of the underlying cold flow. It gets collected and it's done & gone. Hot flow, on the other hand, does not really care too much about if it's being collected or not at that very moment.
The answer is, NO, collect is not only internal kotlinx.coroutines API. The error message is misleading. As per @ir42's comment, add import kotlinx.coroutines.flow.collect solve the problem.
Kotlin flows on Android 1 Creating a flow. To create flows, use the flow builder APIs. ... 2 Modifying the stream. ... 3 Collecting from a flow. ... 4 Catching unexpected exceptions. ... 5 Executing in a different CoroutineContext. ... 6 Flows in Jetpack libraries. ... 7 Convert callback-based APIs to flows. ... 8 Additional flow resources
In coroutines, a flow is a type that can emit multiple values sequentially, as opposed to suspend functions that return only a single value. For example, you can use a flow to receive live updates from a database. Flows are built on top of coroutines and can provide multiple values.
This operator is usually used with onEach, onCompletion and catch operators to process all emitted values and handle an exception that might occur in the upstream flow or during processing, for example: Kotlin™ is protected under the Kotlin Foundation and licensed under the Apache 2 license.
The answer is, NO, collect
is not only internal kotlinx.coroutines API. The error message is misleading.
As per @ir42's comment, add import kotlinx.coroutines.flow.collect
solve the problem.
Additional info, why I didn't pick collectLatest
as the answer
collect
and collectLatest
is different.
Using this example
fun simple(): Flow<Int> = flow { // flow builder for (i in 1..3) { delay(100) // pretend we are doing something useful here emit(i) // emit next value } } fun main() = runBlocking<Unit> { // Launch a concurrent coroutine to check if the main thread is blocked launch { for (k in 1..3) { println("I'm not blocked $k") delay(100) } } // Collect the flow simple().collect { value -> println(value) } }
Collect will produce
I'm not blocked 1 1 I'm not blocked 2 2 I'm not blocked 3 3
as per https://kotlinlang.org/docs/reference/coroutines/flow.html
But collectLatest
fun simple(): Flow<Int> = flow { // flow builder for (i in 1..3) { delay(100) // pretend we are doing something useful here emit(i) // emit next value } } fun main() = runBlocking<Unit> { // Launch a concurrent coroutine to check if the main thread is blocked launch { for (k in 1..3) { println("I'm not blocked $k") delay(100) } } // Collect the flow simple().collectLatest { value -> println(value) } }
will produce
I'm not blocked 1 I'm not blocked 2 1 I'm not blocked 3 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With