delay()
is a suspend function which can be called from a coroutine or another suspend function.
suspend
is a special modifier found in kotlin.
suspending function- A function with a suspend modifier is known as suspending function. The suspending functions are only allowed to be called from a coroutine or another suspending function.
Two ways of creating coroutines-
GlobalScope.launch()
runBlocking()
GlobalScope.launch{}
( & async{}
) is a coroutine which is non-blocking in nature.
runBlocking{}
is a coroutine which blocks the current thread.
Coroutine builders are used for creating coroutine.
Important coroutine builders-
- runBlocking - generally used to write test cases to test the suspending functions.
- launch
- async
e.g. GlobalScope.launch{}, GlobalScope.async{}, runBlocking{}
GlobalScope.launch{} vs launch{}-
GlobalScope.launch{}
is a top level coroutine that can survive the entire lifecycle of the application. GlobalScope is a singleton class.
launch{}
creates coroutine at local scope, get destroyed when current scope get destroyed.
launch{}
(also async{}
) coroutine inherits the properties of the immediate parent coroutine i.e. if you run it inside runBlocking{}
which wraps the main method, it will execute in main thread.
launch vs async-
launch
returns a Job
object.
async
returns a Deferred
object (Deferred
is an interface which implements Job
interface)
launch
starts a new coroutine which does not return the result to the caller - "fire and forget" nature.
async
starts a new coroutine and allows you to return a result with a suspend function called await
.
The coroutine should be cooperative to cancel it.
Cooperative coroutines-
- Only those suspending functions that belong to
kotlinx.coroutine
package will make coroutine cooperative. e.g. delay(),yield(), withContext(), withTimeout()
etc. - Use
CoroutineScope.isActive
boolean flag
Suspending function can not be run from a finally block
Use withContext(NonCancellable){}
to execute suspend function in finally block
withTimeout
withTimeoutOrNull
These are also coroutine builders just like launch and async builders.
Sequential execution- code executes withing a coroutine by default sequential.
Concurrent/parallel execution- can be achieved using async/launch builder
Lazy coroutine execution-
can be achieved using start = CoroutineStart.LAZY
inside async
e.g. async(start = CoroutineStart.LAZY)
. This means if this coroutine's result is not used in the program compiler will not executes a lazy coroutine.
Every coroutine has its own CoroutineScope instance attached to it. CoroutineScope can be accessed using this keyboard from inside the coroutine.
Similar to CoroutineScope, every coroutine has its own CoroutineContext. Unlike CoroutineScope CoroutineContext can be inherited from parent to child. This can be accessed using coroutineContext property from inside a coroutine.
CoroutineContext has two major component-
- Dispatcher- It decides on which thread the coroutine will execute
- Default
- Unconfined
- Main
- IO
- Job- is used to control a coroutine
- CoroutineName