Hi, I’m trying to migrate to the new compose versi...
# compose
n
Hi, I’m trying to migrate to the new compose version and facing this issue:
Copy code
Flow operator functions should not be invoked within composition
Basically, almost all flows of my app are using something like this:
Copy code
val someStateInViewModel by viewModel.myState.flowInLifecycle()
    .collectAsState(initial = null)
This
flowInLifecycle
function is doing the following:
Copy code
@Composable
fun <T> Flow<T>.flowInLifecycle(): Flow<T> {
    val lifecycleOwner = LocalLifecycleOwner.current
    return remember(this, lifecycleOwner) {
        this.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)
    }
}
Any suggestion? Because I’m using this function is 225 places in my app 😭
w
why do you nee flowInLifecycle? My understanding is that coroutines should be able to handle their own subscriptions/unsubscriptions in their state. Does something go wrong if it’s removed?
n
I did this implementation based on this article by @Manuel Vivo https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda
Even if Compose doesn’t recompose the UI when the host activity or fragment is in the background, the flow producer is still active and can waste resources. Compose can suffer from the same problem as the View system.
When collecting flows in Compose, use the 
Flow.flowWithLifecycle
 operator as follows:
t
The reason the warning pops up is to prevent the accidental creation of new
Flow
objects on every recomposition. Your operator doesn't do that (it uses
remember
under the hood), but it also doesn't do anything
collectAsState
doesn't already do, as the coroutine scope it uses doesn't outlive LifecycleScope. If you're using StateFlow then no other operator is required to keep it hot for multiple collectors, but if you want to avoid creating a hot flow for each collector, use
shareIn(viewModelScope)
with the appropriate restart policy in the ViewModel.
n
thanks for the clarification @tad, I’m using
StateFlow
in my viewmodel, so I think I’m good 🙂
a
Might be worth filing feedback for the lint warning, if you declare a flow operator as
@Composable
we could assume you know what you're doing w.r.t. avoiding recomposition causing a cancel/re-collect for a new Flow instance