And this video, you are going to learn how to use routines and why do we need quarantines?
Well, in Android, some operations or tasks take a longer time to complete, and these tasks blocked
the user interface and until they are completed, the user interface is not interactive with so the
user cannot interact with it, or at least with parts of the application and which will make the user
idle and will make him bored and so forth.
So it's not a good process.
It's not a good approach, basically.
So to avoid this, Android's UI system was built to only accept delays of maximum five seconds.
So let's look at that.
So have this little application here, and once I click on this button, there will be a very long lasting
task running.
And let's just run it.
You see, the UI is frozen.
I cannot click on anything.
The app is frozen basically.
And after five seconds, Android decides, Hey, this is a bad application.
It's not responding.
Let's close it, even though you see it's done.
So even though the application did finish in the meantime, while this pop up appears so I can close
the app or I can wait and then go back to the app and it works right?
Otherwise, the user would just close it because he believes the app is bad and he's going to uninstall
it, or she's going to uninstall it.
So what is going on in this application that I've built here?
So I've just this button, and once I click on it, it just runs this full loop, which runs 100000
times and it only adds a log entry.
Nothing too fancy.
And once it's done, it's going to write this toast.
But I'm doing that in the on create, and I'm doing that on the main threats or on the user interface
thread, which really is not good.
And we can avoid that by using code routines, which will basically push tasks that last longer into
the background onto a different thread so that the UI thread will not be blocked and can still run and
will still run flawlessly and fluidly so that the user can properly use it.
So let's look at what called routines are in a little presentation and see the advantages and then build
the little application around it.
So let's look at correlations and those scopes in the little more details.
So to summarize the features of code routines.
First of all, they are lightweight.
This means that you can run many core routines on a single thread due to the support of suspension.
Then you have fewer memory leaks.
By running a routine and a specific scope, you ensure that they do not leak as it terminates at the
end of its scope.
Then you have built in cancellation support.
So the launch option returns a job which can be used to cancel the running call routine, and it is
integrated into jetpack.
So many jetpack libraries include support for Cortines, for example, room and the work manager.
So basically, if you want to develop for Android Wear, then 2021 and later does is definitely going
to be the way to go.
OK, so then let's look at courtin scopes.
So there are built in scopes you can use to launch a Cortines to finally execute this function.
However, we need to tackle routine school and Cortines follow the principle of stent structured concurrency,
as I said, which means that news code genes can only be launched in a specific code routine scope.
So if you create a scope and don't clear it at the end, you can run into memory leaks and you want
to avoid that.
So let's look at the view model scope.
It can be used to launch a call routine, and if you model class, it will automatically be cancelled
once this view model is cleared.
And then you have the lifecycle scope, which is used to launch Cortines in the activity or the fragment
and is cancelled automatically when they are destroyed.
So when the lifecycle is destroyed, which is good because then you are not running into memory leaks
and you can as well create a custom scope, but it is important that you attach it to a job and clear
it when the execution is done to create one in your activity.
You create a global job variable.
You create a call routine scope and attach a job to it and then you execute it.
And finally, you cancel the job when the activity is destroyed.
OK, so this is how you could potentially do it if you were to create your custom scope.
OK, so now let's look at this.
First of all, instead of running this code in here, I'm going to create a little function that I'm
going to then adjust.
So I have this private.
Fun.
Execute.
I'm going to call it, and I'm going to pass a result into it, which will be of type string.
And it's just going to execute my follow.
So here I just want to run the execute method and I need to pass a string to it, which will be.
For example, task.
Here task executed successfully.
All right.
And this should, of course, be used here, so the results should be used as the text of the toast.
OK, so once I execute it now, well, now basically the same thing would happen, only that the toast
message would change slightly.
So that's not really helping us.
So how can we fix the problem that we have?
Well, in order to fix it, we are going to use the suspend keyword here, suspend.
But that will do is it will make it a core routine function.
So a suspend function.
Now, as you see here, it's unhappy.
So you cannot just execute a suspend function on the main threat, which is really the whole idea here.
So now to stop the function from blocking the UI, we need to add suspense in front of the function,
but also we actually need to make sure that it runs on a different thread.
So the suspend function is just part of the call routine class and it has to invoke another suspend
function.
So now let's modify our function block a little bit.
Therefore, I'm using the with context here with context method and then passing a dispatcher thought,
I o here.
So neither of those is recognized, and that has to do with me not having the right implementation here.
So when the right dependencies.
So we need to add this dependency and it's the activity.
Katie X and in my case, the version is one Dot 4.0 beta 01 and you could of course, use a different
version.
But either way, we need to use Caity X activity here and then we need to sync it.
And once this is linked, we will find that we can now add the classes.
And did I read it correctly?
No, I did not.
So with all enter, you see, now we have the two imports up here and we can now use it.
So with context, it's not going to run a call routine.
So now, of course, we need to put our code in there now.
And at this point, backed security up here is still not happy, but at least our code here is more
or less ready.
So here we use the with context method to run.
The task with context is a method created to move an operation into a different thread until it completes
its process.
And then it is moved back into the original thread.
And then we're passing dispatchers.
I o.
Which moves the task to a different threat, which is the input output, Fred, which is different from
the UI Fred.
So it's running on a Fred that is not blocking the user interface.
And when we look at the on click, listen, they're here, we can see that it's not happy, right?
So we need to make a change here.
So in order to make it run, we need to say on which scope we want to run this and I'm going to run
it on the lifecycle scope so we can launch it here and then and then in curly brackets, that's where
we can execute our method.
So in order for this to run, we need to import this launch as well.
And you see here, Colton's launch has been added.
But there are different types of existing quarantine blogs where you can launch a suspend function from
depending on the class it has been called from.
So lifecycle scope is a quarantine block built to properly handle quarantines and any activity class.
So now when we run the application and click on the button after it completes, the app crashes with
an error.
So let's test this.
So you see in the background, it created all of our entries, all of our hundred thousands of entries,
right?
And in the end, it crashed.
OK, so Cortines keeps stop working, so let's close the app, and I still have the other iteration
of the app running.
And our application crashed because of a very simple thing, we are trying to run just toast on our
background threat.
But the toast itself is a foreground or a UI, a task.
OK, so our UI related action like this toast can only be run on the UI thread, but currently we're
running it on this dispatcher's i o thread and this cannot work.
So how can we fix that?
Well, we can add something that we want to run on the UI thread, specifically by calling the run on
UI thread method here, and we can then say what kind of action we want to execute on the UI thread
inside of this call routine.
So here I'm just saying run this on UI thread and particularly the toast should be run on the UI thread.
So let's test this again and see if our application is going to crash and we can see it's running in
the background.
So stuff is happening and our application doesn't crash.
Well, I'm starting it again and again.
So I have multiple iterations of my task, and once it's done, it should display my toaster at the
bottom.
And we could see here.
There it is.
It took quite a while.
But that's just because it takes a while to run the task 200000 times.
So now what we could do is, of course, limit it to ten thousand times.
Then it would run a lot less or 50000, maybe 20000, something like that.
OK.
So that by itself was cool.
But now let's see what is a good approach.
If you have such a situation where you want to run something and you want the user to wait for a response?
Well, what you can do is you can add a progress dialogue.
OK, so I'm going to create this new dialogue entry here, which will be of type, dialogue and dialogue
Nullarbor to be precise and will be null at the beginning.
So this one will be a VAR custom progressed dialogue of type that, OK, let's import it and now we
can use it.
So this will be the progress dialogue, which will just be a dialogue inside of this context and setting
the content to be this dialogue custom progress bar, which is this custom progress bar, which says
Please wait.
OK, so this thing will circle and then this will say, please wait.
And if you look at it, it's just this progress bar with a with a 50 50 with a little bit of margin.
And then we have this text view which says, Please wait.
OK.
So then I have a way to show the progress dialogue.
Now let's add a way to cancel the progress dialogue because otherwise we don't have a clean way of cancelling
the progress dialogue, and I want to be able to cancel it once we are, for example, done with our
execution here.
All right.
So what can we do now?
Well, we can say once we clicked on the button here before we launched a lifecycle scope, let's show
the progress dialogue.
And then once we are done.
And we start running something on the wife thread.
We can cancel it in the thread.
OK, so here cancel progressed dialogue, which handles a progress dialogue which should be also handled
in the way threat.
OK, so progress dialogue, they show something.
If you show something specifically that has to do with the Why Fred?
So let's run the supplication again.
It will be a lot more appealing.
So now we can see you.
Please wait.
And we know that we should wait.
And once the task is done, you see tasks executed successfully.
And you see, even if I click away the wise, the works and the task will still run in the background.
It will succeed successfully and I can run my application cleanly.
So this will make sense for tasks that will take longer, for example, loading data from the internet
or like doing bigger calculations that will just take time.
So that's where it really makes sense to use your call routines.
So just quickly, a summary if you want a function to run as a call routine, you need to add the suspense
keyword you need to add with context and then you say on which context you want this to run.
So on which thread you want this to run the run multiple options.
We're just using the dispatcher's i o here.
And then if you want to execute this function, you need to define on what scope you want this to run.
And I want to run it on the lifecycle scope here.
I launch it and then I can execute my suspend function or my call routine function.
So that's generally the structure that you can use for your call routines.
There is, of course, a lot more to learn about core routines and even have a YouTube video on it where
I go into a lot more depth.
So definitely check that one out and yeah, see you in the next video.