Hello. And welcome. In this lesson, you will learn about the fundamentals of coroutines. So, what are coroutines and why do we need them? In other words, what is the problem? So the problem in software development is the time crunch. It's heavy computations, it's heavy bandwidth, it's slow processing and delays. So the purpose in coroutines for Kotlin. And the reason that Kotlin and developers built coroutines is to get around the delays. So coroutines is a multi-prong, multi-thread approach to a digital brick wall. Okay, so when an application is launched like this onCreate, the first thing that happens is the onCreate builds a default thread, and that thread is called the main thread. And that main thread is doing great when it's doing lightweight operations, such as the user is clicking on a button or any kind of user interaction. And it works great when it's doing simple mathematical operations or simple logic operations. But the problem comes in when the thread encounters a heavy operation, like going up against the internet, maybe a slow network, or it has to get a file from a database, then it has to parse all the data and index all the data. Maybe it has to run a database query or it's uploading or downloading some kind of image off the internet or somebody else's server, or it's just downloading a huge amount of data. So when we have these heavy operations, the thread will become blocked and it will cause our app to hang there. And then the user gets frustrated 'cause they don't know what's going on. All they know is their app is blocked. The app is slowing down. And if it hangs there for a long time, eventually it might crash. So what do we do to solve this issue? We got to unblock it, and that's where coroutines come in. For example, one way that a coroutine gets around this issue is called run blocking. Another way is to put the thread in asleep mode. So to get around this issue, what we have to do is create another thread, maybe a background thread or multi-threads, but we have to be careful because creating all these threads uses up a lot of computer memory. And if your device runs out of memory, that's it, it will crash. So the people at Kotlin invented coroutines, and you can perform that coroutine on any long running task that requires heavy computations. And you can also invoke coroutines that are suspendable so that you can perform these heavy tasks without interfering with the main thread and using up all your memory. So what exactly is a coroutine. Coroutine is in essence, a very lightweight thread that you can suspend or run on top of other threads. So when the coroutine is suspended, all of that computation will be paused and removed from the thread that uses up the memory. And then that thread can be freed up and used for other purposes. And it will not eat into your memory. These coroutines can run concurrently, like we see here launching job one and job two, job three and job four all simultaneously. And these coroutines can communicate with one each other and even wait for another one to finish. These coroutines all work together as one unit doing separate tasks. So coroutines can pause or delay, and then resume when you want it to. You can have complete control over when the coroutine starts and stops and pauses by giving it time limits and time parameters. So we can take a job or a coroutine, and start it and stop it and pause it and resume it and cancel it anytime that we want. So, some important concepts in the coroutine is the concept of scope. Each coroutine has its own scope that we can deal with. Some coroutines or global. Other coroutines only invoke in a local area. Another important concept within coroutines is the context of that coroutine. What are the variables and what are the inputs and what is the data inside of the coroutine that gives a coroutine its character, its makeup? All of that is known as coroutine context. Another important concept of the coroutine is how it can be suspended. Do we run the whole routine? What can this routine be suspended as we call them? Another important concept of coroutines is the job, or the task that is performing at that moment. Jobs are a way of managing our tasks and managing our coroutines, because we might want to pass a coroutine some parameters, and then return those parameters to be used for the next job. Okay, so those are the basic concepts of the functionality that we need for coroutines. So that concludes our lesson on coroutine fundamentals. Thanks for watching. Stay tuned for the next lesson. So let's go.