Kotlin Flow vs LiveData
As the name suggests, you can think of Flow like a continuous flow of multiple asynchronously computed values. The main difference between LiveData and Flow, from my point of view, is that a Flow continuously emits results while LiveData will update when all the data is fetched and return all the values at once. In your example you are fetching single values, which is not exactly what Flow was dsigned for [update: use StateFlow for that].
I don't have a Room example but let's say you are rendering something that takes time, but you wanna display results while rendering and buffering the next results.
private fun render(stuffToPlay: List<Any>): Flow<Sample> = flow {
val sample = Sample()
// computationally intensive operation on stuffToPlay
Thread.sleep(2000)
emit(sample)
}
Then in your 'Playback' function you can for example display the results where stuffToPlay is a List of objects to render, like:
playbackJob = GlobalScope.launch(Dispatchers.Default) {
render(stuffToPlay)
.buffer(1000) // tells the Flow how many values should be calculated in advance
.onCompletion {
// gets called when all stuff got played
}
.collect{sample ->
// collect the next value in the buffered queue
// e.g. display sample
}
}
An important characteristic of Flow is that it's builder code (here render function) only gets executed, when it gets collected, hence its a cold stream.
You can also refer to the docs at Asynchronous Flow
Flow
is sort of a reactive stream
( like rxjava ). There are a bunch of different operators like .map
, buffer()
( anyway less no. Of operator compared to rxJava ). So, one of the main difference between LiveData
and Flow
is that u can subscribe the map computation / transformation
in some other thread using
flowOn(Dispatcher....).
So, for eg :-
flowOf("A","B","C").map { compute(it) }.flowOn(Dispatchers.IO).collect {...} // U can change the execution thread of the computation ( by default its in the same dispatcher as collect )
With LiveData
and map
, the above can't be achieved directly !
So its recommended to keep flow in the repository level , and make the livedata a bridge between the UI and the repository !
The main difference is that
- Generally a regular
flow
is not lifecycle aware butliveData
is lifecyle aware. ( we can use stateFlow in conjunction withrepeatOnLifecycle
to make it lifecycle aware ) flow
has got a bunch of different operators whichlivedata
doesn't have !
But again , Its up to u how do u wanna construct your project !