Categories
blog kotlin

SharedFlow

Intro

This is a third article in the series, please check out the other two articles here: 1st, 2nd

What is SharedFlow?

SharedFlow is a hot flow, it will emit data even though there are no observers/collectors. It’s important to mention this because everything will make more sense if this basic idea of hot vs cold flows/streams is understood. LiveData was a bit under-engineered in my option due to this fact, it was retrofitted to behave as both hot and cold stream, which did not work well and required some patching after the fact. 

When to use it?

It’s perfect for displaying one-off events like error messages and notifications to users. Since a hot flow will not re-emit values to new subscribers and it does not keep state, it’s impossible to display the same event twice. Although it can be customized, by default, it’s still a hot flow. 

When not to use it?

State management, since it does not keep any state SharedFlow is not suitable for state management, new subscribers won’t get the latest state. This can be tweaked also but by default, it does not work well for state management. 

SharedFlow vs Livedata

Those readers who used SingleLiveData or Event class with LiveData are familiar with hacks required to make LiveData behave like a hot flow. SharedFlow fills in that gap and makes it easy to handle one-off events like error messages. 

Nice to know SharedFlow APIs

With SharedFlow we can control how many last n events are played back to new subscribers, which is handy when we wanna maintain some state. extraBufferCapacity is handy when it comes to slow consumers, extra buffer capacity will let SharedFlow have additional items on top of the replayCache that helps slow subscribers get through all events

Categories
blog kotlin

StateFlow

Intro

If you need a refresher on hot vs cold flows check out the first article in the series

Hot flow

StateFlow is a hot flow and that means it will be alive and running even though subscriber count is zero. It’s very useful for state management since we want the state to be up to date even if no one is observing it so that when a new subscriber comes the latest, the correct state can be shown on the screen. Another nice feature of StateFlow is the .value parameter, it’s an easy and convenient way of reading the latest value without the need for launching coroutines.

Do we need a hot flow for state management?

If we think about the state of a screen and its logic, let’s say whether a user is signed in or not, does that state depend on an observer? Should it? It should not. If a user completes the sign-in flow, it does not matter if there was an observer to that event, we should be able to persist the fact that the user signed in. Otherwise, we would always need an observer to keep the state “correct, which is not ideal. That is why we need hot flow for state management, and we need the ability to broadcast the latest state to any new subscriber. 

Do we need StateFlow?

Can we just use regular Flow and let a flow handle app states? The problem with regular flows is that they are cold, they are not active if they don’t have any observers/subscribers. This is problematic since we want our state to be up to date and be available at all times. Regular flows are not a good use case for state management. StateFlow on the other hand is the opposite, it is a hot flow which means it will hold its value no matter if there are observers or not.

When to use it?

When we need to keep any kind of state and we want the last value to be accessible directly (through .value) StateFlow is idea for that

When not to use it?

In case we need something to behave like a cold flow. One good example of that is error events, we don’t want to keep errors and show them multiple times, ideally, we would show it only if there are observers and we don’t wanna keep errors stored because that would mean we could potentially show the same error multiple times. This was a common issue with LiveData, it needed a hack (SingleLiveData) in order to show an event only once. 

In the next article, we will explore the world of SharedFlow and how we can leverage it’s API