HelloCW
HelloCW

Reputation: 2365

Do I need to operate StateFlow in a coroutine?

I have read the article, I know the Flow need to operate in coroutine, such as Code A.

StateFlow inherited from Flow, I think I should operate StateFlow in a coroutine.

The Code B is from the sample project.

It seems that fun openDrawer() operate MutableStateFlow directly without in a suspend function, why?

Code A

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) } 
}

Code B

class MainViewModel : ViewModel() {

    private val _drawerShouldBeOpened = MutableStateFlow(false)
    val drawerShouldBeOpened: StateFlow<Boolean> = _drawerShouldBeOpened

    fun openDrawer() {
        _drawerShouldBeOpened.value = true
    }
    fun resetOpenDrawerAction() {
        _drawerShouldBeOpened.value = false
    }
}

Upvotes: 1

Views: 451

Answers (1)

Evgeny  Bovykin
Evgeny Bovykin

Reputation: 3079

That's because writing to the value fields doesn't require the suspend context. So it's setter is not suspend.

But to actually subscribe on the value updates, you need the suspend context, since collect method is suspend.

See the Android docs for more examples.

Upvotes: 1

Related Questions