Flow Basics - The Ultimate Guide to Kotlin Flows (Part 1)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back to new video and a new playlist in which i will deep dive into kotlin flows i know i already have some videos about that like about state flow share flow like how they compare and i think also a video about flows in general but i thought that i don't really have a video that really deep dives into flows and that really covers everything from a to z and since i found flows to be super important for android development because i use them pretty much every day i think it's actually helpful to have a dedicated playlist for flows so you can actually watch that from the beginning to the end and then you will actually know everything you need in practice so this playlist will consist of three videos in total in the first video which is this one you will learn just what a flow is and how we can actually use it how we can observe values from it and in the second video i will actually deep dive into flow operators don't worry if you have no idea what that is in the second video you will know and in the third video i will actually also go into state flow and share flow a little bit more in detail so yeah you can also understand these so let's actually start with a little bit of theory which is actually necessary to understand flows so what is actually a flow in kotlin if you're familiar with the term reactive programming then it's basically that if you're not familiar with the term reactive programming let me explain that first so it's basically all about being notified about any changes in your code and then doing something with these changes so you want we want to transform these notify maybe our ui layer to update it and stuff like that but in the end you can think of it just like an assembly line for let's say android phones so in the first the first thing that happens is that the android phone is produced so the basic prototype is produced then we're notified about that so that is the first part of the reactive programming paradigm that we're actually notified about a change so about the production of the android phone then we're actually not done yet because we want to do further steps with that so it's actually put on the assembly line and then as it moves forward we actually do something with it so the first step we might want to give it a color and in the second step we might want to package it and then in the third step we just put it in a big box so it's actually ready to be shipped and in android it's it's nothing else in kotlin rather cotton flows are just a framework to do exactly that with our code so real world example where this would be applied would be let's say you make an api request you get the response you kind of want to map the response to something else that you actually want to display new ui maybe you you get a list and you want to filter it first so you only get a specific specific type of entries in that list and in the end you show that in your ui so it's basically a pipeline of actions that you apply before you actually display something in the ui or before you actually do something uh some kind of final step and now getting to the more technical part here a flow is in the end just a kotlin curoutine that is able to emit multiple values over a period of time so a single current in a single suspend function can only return a single value so if you have a function then of course you can only have that return statement that single return statement and if your code reaches that point then the function is over however if you want to do something like a countdown timer that emits a value every single second then you can't do that with a normal curious because how are you going to be notified about a specific value every single second and that is where cotton flows actually come into play because with that we can actually do stuff like that and i think this is actually a very good starting point here to just create a very simple countdown timer using a kotlin flow and then you will actually get a very first understanding of how this will work so let's actually jump into android studio so i am in an empty jetpack composed project here if you have no idea of jetpack compose don't worry this playlist will not really use it a lot here we are just going to use it to display a number and that's all ui related stuff we will actually do here in this playlist so even if you don't know it just just follow this playlist it's the focus is really on flows so let's first of all actually create a view model here just to have some kind of structure so in our root package i will create a main view model select class and it will just contain our flow logic nothing special here let's make that inherit from viewmodel and now as i said we want to have a flow that has some kind of starting value for our timer for a countdown timer and then basically counts down by one second and notifies our ui about that change that is what we want to do so let's first actually take a look at how we can create such a flow we can do that just using val here like a normal cotton property valve flow or let's call it countdown flow count down below maybe like that rather and then we have a so-called flow builder that is just a normal builder block so this flow with this lambda block here and we have to declare type that will be the type of the values we want to emit over time since we have a count on timer well we want to emit numbers so in the end integers and now inside of this block you can see this is a flow collector of type in now instead of this block we can pretty much emit values over time so this is in the end okay routine we can execute suspend functions inside of this block which we are actually going to do now so let's actually start by just declaring oops by just declaring a starting value so let's say val's starting value which is the value or count on start at let's say at 10 seconds then we also want to have a current value that basically counts down that must be a var because we want to change it every second so our current value is equal to starting value so that is just that we we start at 10 seconds and then we can now have a loop in which we count down so let's have that loop simply a while loop and as long as the current value is actually greater than 0 we want to count down i think it's pretty clear till now so what do we actually want to do in this loop well we want to delay the curtin this flow is actually running in so that's the cool part now that we can execute these suspend functions so we can say we delay this execution here by one second by a thousand milliseconds before we actually do something before we say current value minus minus to just decrease it by one and then we now somehow want to notify our ui about that change we want to say hey our current value our current second actually just decreased please show that in the ui so let's do that by using emit so that is the function we actually have in this flow collector here and we can now emit an integer value here and whenever we call limit in our flow our ui in the end will receive that change or it's it doesn't always need to be the ui it can also be some other part of code but it's typically the ui layer that wants to just be notified about any changes that require some yeah some asynchronous actions so you want to say emit current value because we just decrease it and then we emit that we can also emit before the while loop so we actually also emit the starting value otherwise it will actually start at 9 in this case in our ui so we just say emit starting value all in all we just start at 10 we set the current value to 10 we emit 10 so our ui will then show 10 in the text view and as long as the current value is actually greater than zero we want to run our timer we say okay we wait a second after a second we decrease the value and we say okay ui layer we actually change the value please now show nine instead and now let's jump into main activity and actually show that to see how this works let's just have a box to center this uh this text we can say modifier is modifier filmex size and then we say we have a text and well what do we now show here in this text in the end we want to show every single emission so if you're a little bit familiar with compose you know that we need that kind of as a state because that will make our ui redraw if you don't compose that's basically how it works don't worry about this part now we can basically just say val viewmodel first you want to get a reference to review model is equal to viewmodel if you don't have that by the way that needs to be a main view model if you don't have this function and then make sure you actually include this dependency that just brings it and then with this view model we can actually now get our flow as state so that is just a function to transform that to state as i said i will also show you the other way to actually get these changes if you don't use compose but here we're just going to say val let's say val number of valve time i think is better is equal to viewmodel countdown flow and we can say collect as state and we need to provide an initial value which is 10 here and that is now our integer value that is changed every single time our countdown flow actually counts down so we can say okay the text is time.2string let's increase the font size a little bit to let's say 30 sp and we want to make sure it's centered so modifier we align center and that is it let's actually launch that in our emulator and see if this actually works so here we go here the app is launching and oh i actually made a mistake it's not the timer to string it's actually time that value.string because otherwise we refer to the state and not to the value of the state so let's relaunch that quickly and now we see 10 9 8 and you can see the countdown is working pretty good so that is how we can actually do that with compose but very often you don't want to do that either in compose or in your ui layer you still want to be notified about changes of a specific flow let's jump into our main v model for that and write a function here that actually collects that flow so that is how we call it when we actually listen to these changes so we basically just yeah we're just notified about each change let's do that with a private function collect yeah maybe collect flow and since that is actually a suspending action here to collect that we want to execute that in a croutine so i want to save your model scope that launch and here we can say flow actually countdown flow dot collect you can see we have collect and we have collect latest what the difference is i will actually also get you in this video but let's actually start with collect which is the more simple one of these and here we now get the time value so this block is now triggered every single time when we call emit here in our flow so we could simply say print line the current time is and then simply insert our time making sure that we also call this function so collect flow and if we then relaunch our app and actually this time take a look in logcat and search for the current time is then you can see it's actually working exactly the same way so that is how we can collect flows if we don't use the compose state please don't just do it like this in your ui layer don't just use lifecycle scope.launch and then collect it there is this is more difficult if you want to do this and i will get to this stuff later in this playlist but if you just want to listen to changes like your new view model then doing it like this is totally fine now as i said there is also collect latest which is also commonly used actually what is the difference now to collect so if we just take could collect then this is executed for every single emission of this flow well collect latest in and of itself will also be executed i mean this block will also be executed for every single emission but there is a major difference if this block here for some reason takes some time and is not finished yet and we get a new emission then the block will be cancelled so it will only actually execute the last the last emission in the end so let me show you something to actually demonstrate this if we add a delay block in here because that in the end is also a suspend function let's say we delay this by 500 milliseconds so half a second oh no you know what let's actually do it a little bit more let's say 1.5 seconds so this block will actually take roughly 1.5 seconds to finish however new emissions are coming in every single second so there are more emissions coming in than we actually can process at a time but what collect latest will now do is it will cancel the old running emission if there is a new emission coming in so you will see how that works in our lock-it in a moment if we use collect like that and we launch it then it will look pretty much the same as before just that every emission is just delayed by 1.5 seconds you can see it just takes a little bit longer to actually collect these emissions but in and of itself it just works exactly the same however if we say collect latest and we relaunch this then you will see nothing happens but if we wait for a moment then you can see now we get the current time is zero so we only actually get a single emission here if we use collect latest the reason is simply because let's let's take the example of the first emission which is 10. so this is triggered with the value of 10. we delayed this for 1.5 seconds and after that we would print this but because we delayed this for so long and another value is actually coming in after one second but we delay it for 1.5 seconds this block is actually cancelled so it will never reach that print line statement and only for that very last emission in this case which is zero there is no emission that comes afterwards so the last plug is not cancelled and it will actually print that now you might wonder why would that be helpful well on this countdown timer it wouldn't be helpful because we of course want to have every single value of that countdown however if you have some kind of flow that reflects your ui state then collect latest definitely makes sense because in your ui you always want to show the very latest state and you don't want to show a previous state just because it takes a little bit more time to process so you can roughly say that for all one-time events like a count on timer which is in the end yeah just a one-time thing when a value is actually counting down for that you can use collect and for actually reflecting ui state you can use collect latest but as i said i will also get more into that in the last video of this playlist where i will talk about state flow and shared flow which is more about these events and state and finally something that is also worth mentioning here is that a normal flow like we actually have here is a so-called code flow so cold flow means this is in the end doing nothing it doesn't do anything as long as there are no subscribers so as long as there are there are no functions or scopes here that collect something from that flow just as soon as that happens as soon as we call this line this flow will actually do something and that is basically what a code flow means on the other side a hot flow would be also emitting values even if there are no collectors but yeah we will we will find some and get to know some hot flows as well in this playlist so actually be tuned for that and as soon as the next video is out which is about flow operators so how we can actually transform results from a flow then you will actually be able to simply click here and watch that
Info
Channel: Philipp Lackner
Views: 9,954
Rating: undefined out of 5
Keywords: android, tutorial, philip, philipp, filipp, filip, fillip, fillipp, phillipp, phillip, lackener, leckener, leckner, lackner, kotlin, mobile
Id: ZX8VsqNO_Ss
Channel Id: undefined
Length: 17min 25sec (1045 seconds)
Published: Tue Dec 07 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.