Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Kotlin Flow's Collect is only internal kotlinx.coroutines API?

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?

like image 214
Elye Avatar asked Jan 04 '21 07:01

Elye


People also ask

Is kotlin flow collect blocking?

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.

What is experimental coroutines API?

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.

Is flow a coroutine?

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.

What is cold flow and hot flow in Kotlin?

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.

Is collect is only internal kotlinx API?

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.

How to create a flow in Kotlin for Android?

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

What is a flow in a coroutine?

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.

What is the use of Oneach in Kotlin?

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.


1 Answers

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 
like image 50
Elye Avatar answered Sep 19 '22 14:09

Elye