Hot flow as final observable?

Viewed 375

I recently discovered Flows in Kotlin and ever since been trying to optimize the code and making it more readable by avoiding MediatorLiveData and friends.

I try to use Flow in my back ends and finally present it as LiveData to the UI. However, I am having an issue with LiveData unsubscribing after a timeout, which causes the cold flows to recalculate (and make a new network request) each time the timeout is exceeded. Is there any way around it?

Here's the problem:

private val storeProducts = combine(_currentBasket, _currentProduct) { basket, product ->
    // network operation
}
val storeProductsLive = storeProducts.asLiveData()

From the above example, my UI observes it as a normal livedata observable. When I rotate my screen, everything works fine and the last value is returned. However, if I navigate to a subfragment and go back after 5s or if I go out of the app and return later, the network operation is done again. the .asLiveData() specifies a default timeout of 5s, after that the Flow is cancelled.

My current workaround:

private val productsState = MutableStateFlow<List<Product>>(emptyList())
init {
    viewModelScope.launch {
        storeProducts.collect {
            productsState.value = it
        }
    }
}

However, this is quite hacky and it means the observer is always registered, regardless whether the UI actually cares about it. Any way around it?

UPDATE Within an hour, I found another workaround (described here: https://github.com/Kotlin/kotlinx.coroutines/issues/2140 ):

val storeProductsLive: LiveData<List<Product>> by lazy {
    MutableStateFlow<List<Product>>(emptyList()).apply {
        viewModelScope.launch {
            storeProducts.collect { value = it }
        }
    }.asLiveData()
}

Is this the recommended way?

0 Answers
Related