StateFlow vs. Flow vs. SharedFlow vs. LiveData... When to Use What?! - Android Studio Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back to new video in this video i will give you an overview over these typical observables we have an android like live data state flow normal flow shared flow compose state because all these are quite similar but they differ in some minor aspects and i want to show you in this video and i want to give you more clarity over this topic how you actually can use these in your project and especially for which scenarios you should use which so by making sure that you watch this till the end you also make sure that you actually won't have many more questions around this topic and you actually know when to use these things as you can see i created a little demo app here to actually show you the differences right now this app doesn't do anything i just have some initial setup just to show you we just have a four different of these observables here live data state flow normal flow and shared flow there's also compost date which i can't use here because it's an xml project it's just better to demonstrate this in an xml project but most of these also can be used in compose projects so all that happens here is or that i want to happen when we click these buttons then right now nothing happens but we actually make a call to our review model that triggers in this case a live data that should change the value of this text here we trigger a state flow that changes the value of this text your normal flow and the shared flow so just that i can show you the differences of these different uh observables but right now we don't observe anything here so nothing no ui changes i just implemented this these functions here to trigger the viewmodel functions which you can see here so let's actually go through this step by step i will show you how you can observe these values how you can create these objects starting with the live data actually i think live video will be the most well known observable pattern here that we have in this list because it's just the oldest it belongs to the android jetpack components and it's actually also the only one that works on java here so in java projects you have to use that um i hope you don't use java anymore for android but if you do you have to use live data so what does it do live data is a so-called state holder so it holds our ui state in the end if if any value in your ui changes over time then that change so for example the new string that should be reflected here in our ui that needs to be stored somehow because otherwise it will be lost on screen rotations and that's what live data does so you can put the state in live data and when the activity rotates all the observers will automatically be notified about the current value so you can see when we trigger livedata here we just change the value to livedata let's see how that works when we want to observe that in mainactivity here in subscribe to observables it's important to mention that lifetime is actually lifecycle aware so it will only fire off the the new value or the the current value if the corresponding life cycle is actually in a state where it should receive these um where it should receive the that data like if it's if the activity is in the foreground basically so we want to say view model live data and we say observe so that will now be called whenever the there is a change on the livedata value we need to pass a lifecycle owner here we just pass this because it's the activity if you have that in a fragment you use view life cycle owner instead but since we don't have that we pass this and down in here you can see we get a string which is the new value of the live data we can just say we use our binding our text view live data and we set the text to whatever we got from the live if we then relaunch our app to show you a little demo of how that works then you can see if we now click on a live data here then we will trigger the event in our review model here we will assign a new value to our live data which is this so this live data now holds live data as a string and not hello world anymore this because we made it the change will then trigger the observer here this block and we change the text to whatever is in the live data and the thing about livedata is now if we rotate our device it will automatically fire off again so you can see it keeps the value and the text won't be hello world again so far so good let's get to state flow and how it compares to live data estate flow as the name already suggests also holds state as well as live trader so it's also just a stateholder class however it's a little bit different than live data state flow as the name also says is is a flow so if you know kotlin flows i will get more into this in this video here then a flow is basically comparable to life there but it can actually do a little bit more so in regards to state flow this is very similar to live data i will get to the other flows here in a moment but the state flow is the most comparable one to laughter because it's used to also store state and it is basically a flow so we have the flow benefits which i will get to in a moment you can see we can we can change the state flow value exactly the same way as here for live data and then to actually be able to observe from that we actually need to do that in a curtain because a flow is uh based on the curitin framework in kotlin so we need to launch a curtain here in lifecycle scope which is um lifecycle scope launch when started always use launch when started here never use launch to collect from a state flow and here we say view model state flow collect latest and that's basically now the equivalent to this so this will now be fired up every time the state flow value changes so in here we can say binding tvstateflow.text is equal to it and if we relaunch this you will see it will have the exact same behavior as our livedata here so there we go you can see if we click live and state flow both these values change and if we rotate the the screen then both these values here will actually stay in in the corresponding text views so the state is just kept which is exactly the job of a stateholder class so which of these two should you actually now use so in the end they do the same thing so which should you actually use in your project i personally recommend not using livedata anymore because it's just kind of obsolete and the flow that the stateflow version just can do a little bit more with stateflow we have all these powerful flow operators which you might know you can map the results easily you can filter them and also flows are much easier testable actually than live data because they use coroutines um the the testing capabilities for curtins are great because you can test time in the end very easily because for test cases the delay of curotenes are just skipped so yeah personally i always use stateflow in my projects assuming it's not a composed project just a normal xml one um then i always use state flow it's just better than live data get used to it it's great something that's also worth mentioning here is that there are heart flows and there are cold flows state flow is a so-called heart flow and that means that it will it will keep emitting values even if there are no collectors a code flow would mean it would not emit anything if there is no collector so you can see this would be a collector here and even if we wouldn't have that and we change um the value here of state flow in our view model the state follow the stat flow would still emit something even though there is nobody to collect that so that's just worth mentioning here because we will also get to some code flows in this video so the next observable here that i want to show you is just a normal flow you can see i don't have that here in the view model really i mean not as a variable instead we have this function trigger flow which returns a flow and we have to do it like that because that is how normal flows work we have to construct these flows with this flow builder here and then inside of this flow builder we have a protein scope in which you can execute suspend functions as you can see and with this emit function we can say now i want to emit a value and trigger our observers so the normal flow doesn't work like stateflow in the way that we can say flow.value is something because it doesn't hold a value instead it just does something and while it's doing something it can emit different values over a period of time so all that flow does here is it repeats the block here five times it will emit a string that gives us the the current iteration delays the flow for a second and then just does that five times basically leading to five emissions in total and after that it will just be cancelled or we'll just quit so we can actually subscribe to that the same way we do for state flow because both are flows we don't do that here on subscribe to observables because we want to trigger that when we actually click on the button so here that now returns that flow and we can say that collect latest which will also give us these strings don't forget to do that in lifecycle scope dot launch um here we can actually use launch because it it's not a state flow and here we simply want to say binding tv flow text is it if we now relaunch this then you will see how that now works so while these two here were stateholder flows or live data the flow one the normal flow will now work a little differently so if we click that you can see we get the emission zero one two three four and after that the value will just stay in the text view because the flow actually finished with its five um repetitions however if we now rotate the device you see live data and state flow stays there but the flow one actually changes back to hello world because the normal flow does not contain a state so it it doesn't just fire off something again when the activity is actually recreated instead it's it's more like a one-time thing so when we trigger the flow we can do that again then it will just create that new flow and emit these values over time and when it's done it's done then then the flow is done last but not least let's get to shared flow and actually compose data that's a little bit differently than all of these um but shared flow is actually also flow surprise surprise and you can see we can construct it uh in a similar way then we can state flow we don't provide an initial value here because a shared flow um just as a normal flow does not keep a value in itself it's the same as a state flow in the sense of that it's also a hot flow so shear flow and state flow are both hard flows so they will send out events or they will send out new data or events even if there are no collectors but what is the difference now well a shared flow is more used to to send one-time events because yeah let's take the the typical example in android of showing a toast or a snack bar let's say you would actually trigger a state flow when you actually want to show a snack bar that would mean that here where we actually observed that we can actually do that to to demonstrate that i think that that makes it clearer let's say here we want to show snack bar um snackbar.make we can say binding.root and we can say it snagbar length long and show so whenever the state flow triggers we want to show snapboard let's say we get some kind of event in the viewmodel let's say we get an api response that was an error and we now want to show that error in our ui so what we do is in the viewmodel when we know there is an error we say our stateflow value is that error or whatever and if we now relaunch that and take a look then if we now click state flow you can see we just get a snack bar with a state flow if we do that again we don't get it because uh it actually keeps a value and it won't emit the same value again however if we now rotate the device you can see the snack bar shows up again because that's the behavior of state flow it will automatically emit the value when the activity is actually recreated and that's usually not what you want with snack bars so they should actually just show up once and that's it even if there are screen rotations in future you don't want to show that error snack bar over and over again and that is now where a shared flow comes into play because it just sends out a one-time event that isn't re-emitted on screen rotation so if you take a look we can trigger the shared flow by using a curtain here and just calling emit so it's similar to a normal flow just that we can call this emit function outside of the flow cutoff so we don't need this flow builder where we construct how the flow works once and then it just works that way instead we can just say somewhere in our viewmodel we now want to send an event into this flow and then let's actually go back to main activity and i'll just change this to shadow here for convenience because i think stateful should be pretty clear now relaunching this and if we now click on shared flow you can see we see a snag bar if we rotate this we don't see a snag bar but we can still click here to see another one and another one and so on so it's just used to send out one-time events when a specific user action happens or when you get an api response something like that it's also very helpful for example if you do something in your view model and validate something and based on this validation you might want to navigate to a different screen so then you can say from the viewmodel if the validation or whatever is successful you just emit an event you can create some kind of event class here that says navigate and you could even pass a route where you want to navigate and then here in your activity or fragment when you receive that navigation event you know okay now the viewmodel actually sent me that event and i should now use my nav controller to navigate to that corresponding page so while the normal flow is more more used to here if you have some kind of logic that yeah emits multiple values over a period of time so i would say a flow is just a curtain that can emit multiple values while accurity in just a normal suspend function can only reach on a single function when it's done a flow can emit these values so it doesn't need to say return that value it can say emit it can use suspend functions to delay these emissions to send these at different times so if you need that behavior use a normal flow and if you need this this behavior to send events from somewhere in your viewmodel to your ui then you want to use a shared flow so something i use the normal flow for was for example a timer so you could say repeat for let's say 60 seconds you delay that for a second and every second you just make an emission you can collect that emission in your ui and you can actually display that so that would already be a very simple 60 second timer here where you say um we just emit it maybe it's plus one here because it starts at the at zero would then be a flow of integers but that would be that would basically start the flow it would emit the the corresponding second every second and then you can observe on that in your ui and you already have a working timer so that's what the normal flow is really cool for and then lastly i want to talk a little bit about the compose state because it kind of belongs in this list here but it's it's not really the same as a flow or a live dealer it is the same in the sense that it's also state holder class it's just called state and compose but it works quite differently because in compose we have to use that so we are forced to use it or if you use a state flow then there is a function to actually call i think it's collect as compose state or so to convert that to compose date but in the end in your ui you have to use these compose states the reason for that is that the compose framework is built in a way that whenever these compose states change the the composables that are affected by this change will actually recompose and will be redrawn so that the actual change is reflected in your ui so yeah what i'm trying to say is whenever you use jetpack compose you want to use the compose state if you use xml then i suggest using all these flow versions here of these observables so so don't use data anymore use the state flow if you want to save state use the share flow if you want to send events to your ui and use a normal flow if you just have some logic and you want to emit multiple values over a period of time so i hope this video was helpful for you and it actually helped you to understand these concepts and also the differences between these if so then you will definitely also love my free email newsletter in which i regularly talk about android architecture about kotlin android advice so feel free to click the link down below and subscribe for that email newsletter for free thanks again and have an amazing day see you next video bye bye
Info
Channel: Philipp Lackner
Views: 15,683
Rating: 4.9803343 out of 5
Keywords: android, tutorial, philip, philipp, filipp, filip, fillip, fillipp, phillipp, phillip, lackener, leckener, leckner, lackner, kotlin, mobile
Id: 6Jc6-INantQ
Channel Id: undefined
Length: 18min 8sec (1088 seconds)
Published: Sat Oct 30 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.