The basic use of coroutines in Kotlin

1. How to create a coroutine

1. Use launch()

  • Examples are as follows:
GlobalScope.launch {
        delay(3000)
    }
  • The source code of the launch() function is as follows:
public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}

context :

Receives an optional CoroutineContext parameter, which is a collection of some elements, mainly including Job and CoroutineDispatcher elements. Can represent a scene of a coroutine. The default value of EmptyCoroutineContext means running in the context of the parent coroutine. Other values ​​are as follows

  1. Dispatchers.Unconfined: The coroutine scheduler will be started in the caller thread when the program runs to the first suspension point. After being suspended, it will resume in the thread where the suspended function was executed, and the resumed thread depends entirely on which thread the suspended function is executed in. The unrestricted scheduler is suitable for the situation where the coroutine does not consume CPU time and does not update any shared data (such as UI) restricted to a specific thread.

  2. Dispatchers.Default: Will get the default scheduler and use the shared background thread pool

  3. newSingleThreadContext("MyOwnThread"): will make it acquire a new thread, both must be released in the real application, when it is no longer needed, use the close function, or store it in a top-level variable It is reused throughout the application.

  4. Dispatchers.IO : Run in IO thread

  5. Dispatchers.Main: run in the main thread

  6. newFixedThreadPoolContext(2, "ss"): Run in a new thread pool, use the close function when it is no longer needed, or store it in a top-level variable to make it reused in the entire application.

  • The job of the coroutine is part of its context. The coroutine can use the coroutineContext[Job] expression to retrieve it in the context it belongs to:
    println("My job is ${coroutineContext[Job]}")
    determine the state of the coroutine

start :

The settings of the coroutine startup, generally use the default values, and have not yet encountered the use of other values

block :

The code that needs to be executed in the coroutine

The return value is a Job object

2. Use async()

  • Examples are as follows:
GlobalScope.async {
        delay(3000)
    }
  • The aysnc() function is the same as the launch() function, the only difference is that it has a return value, because async {} returns a Deferred type. Obtaining the return value of async {} requires the await() function, which is also a suspend function. When called, it suspends the current coroutine until the code in async is executed and returns a certain value.

3. Use withContext{}

  • Examples are as follows:
 GlobalScope.async (Dispatchers.Main) {
                withContext(coroutineContext){
                    delay4s()
                }
        }
  • withContext {} will not create a new coroutine, run the suspended code block on the specified coroutine, and suspend the coroutine until the code block is completed.

4. Use runBlocking {}

  • Examples are as follows:
fun main() = runBlocking {
    delay(1000)
}
  • runBlocking {} is to create a new coroutine while blocking the current thread until the coroutine ends. This should not be used in the coroutine, it is mainly designed for the main function and testing.

  • In Android, the GlobalScope.async() function and GlobalScope.launch() function are generally used to start the coroutine. They correspond to the async() and launch() functions, but the life cycle of their coroutine is only affected by the life cycle of the entire application. limit. Then, among these two functions, you can use the above functions to create sub-coroutines. And the new coroutines created by GlobalScope.launch{} and GlobalScope.async{} do not have a parent coroutine.


2. Job & Deferred

  • Job, task, encapsulates the code logic that needs to be executed in the coroutine. Job can be cancelled and has a simple life cycle. It has three states:

Insert picture description here

  • When the job is completed, there is no return value. If you need a return value, you should use Deferred, which is a subclass of Job. The return value can be obtained through the await() function

Guess you like

Origin blog.csdn.net/genmenu/article/details/87258789