Personal blog

www.milovetingting.cn

Kotlin coroutines

preface

This article is a simple note of Kotlin coroutine, because of new contact with Kotlin language, if there is a misunderstanding, in order to avoid misleading others, can leave a comment, so that I timely modify, thank you guys! For more advanced articles on coroutines, please refer to other related materials!

What is a coroutine

Coroutines are a concurrent design pattern that is used on the Android platform to simplify code that executes asynchronously.

This is a simple definition of coroutines in the official documentation.

The following code shows the specific use of coroutines.

Suppose you have the following requirement: You have a time-consuming task to execute, and when it’s finished, you need to refresh the UI in the main thread.

Don’t use coroutines

Call the following methods in the Activity’s onCreate


io()

ui()

private fun io(a) {
        thread {
            Log.d(TAG, "io method,thread:${Thread.currentThread().name}")
            delay(1000)}}private fun ui(a) {
        Log.d(TAG, "ui method,thread:${Thread.currentThread().name}")}Copy the code

Output log:

The 2020-09-25 23:10:25. 854, 5208-5208 / com. Wangyz. Coroutines D/Coroutine: UI method, thread: main 23:10:25. 2020-09-25, 855, 5208-5267 / com. Wangyz. Coroutines D/Coroutine: IO method, thread: thread - 2Copy the code

The IO () and UI () methods are called, respectively, in the child thread and the main thread, but because of the time-consuming operations of the child thread, the main thread methods are executed first, so the desired sequence is not achieved.

Modify code:

io2()

private fun io2(a) {
        thread {
            Log.d(TAG, "io method,thread:${Thread.currentThread().name}")
            delay(1000)
            runOnUiThread {
                ui2()
            }
        }
    }

    private fun ui2(a) {
        Log.d(TAG, "ui method,thread:${Thread.currentThread().name}")}Copy the code

Switch the thread to the main thread with runOnUiThread in the child thread, and output:

The 2020-09-25 23:16:44. 753, 5597-5641 / com. Wangyz. Coroutines D/Coroutine: IO method, thread: thread - 2 2020-09-25 23:16:45. 756, 5597-5597 / com wangyz. Coroutines D/Coroutine: UI method, thread: mainCopy the code

Now let’s look at how coroutines are implemented

Using coroutines

Dependency information

To use coroutines in an Android project, add the following dependencies to your application’s build.gradle file:

dependencies {
    implementation 'org. Jetbrains. Kotlinx: kotlinx coroutines - android: 1.3.9'
}
Copy the code

Use of coroutines

GlobalScope.launch(Dispatchers.Main) {
            io3()
            ui3()
        }

private suspend fun io3(){
        withContext(Dispatchers.IO){
            Log.d(TAG, "io method,thread:${Thread.currentThread().name}")
            delay(1000)
        }
    }

    private fun ui3() {
        Log.d(TAG, "ui method,thread:${Thread.currentThread().name}")
    }
Copy the code

In IO3, a thread is started with withContext and dispatchers. IO is run on the IO thread. Suspend is a flag indicating that there is a suspend operation inside the method. It does not cause threads to switch. Threads are actually switched with withContext.

Output result:

The 2020-09-25 23:28:19. 965, 6017-6062 / com. Wangyz. Coroutines D/Coroutine: IO method, thread: DefaultDispatcher - 2020-09-25 23:28:20 worker - 1. 969, 6017-6017 / com wangyz. Coroutines D/Coroutine: ui method,thread:mainCopy the code

Suppose we need to request multiple interfaces at the same time, and update the interface uniformly after they all return data. The following uses coroutines to simulate this requirement.

Request multiple asynchronous interfaces

GlobalScope.launch(Dispatchers.Main) {
            val res1 = async { io4() }
            val res2 = async { io5() }
            val data = res1.await() + res2.await()
            ui4(data)}private suspend fun io4(a) = withContext(
        Dispatchers.IO
    ) {
        delay(2000)
        Log.d(TAG, "io method,thread:${Thread.currentThread().name}")
        1
    }

    private suspend fun io5(a) = withContext(
        Dispatchers.IO
    ) {
        delay(3000)
        Log.d(TAG, "io method,thread:${Thread.currentThread().name}")
        2
    }

    private fun ui4(value: Int) {
        Log.d(TAG, "ui method,thread:${Thread.currentThread().name},result:${value}")}Copy the code

Output result:

The 2020-09-25 23:51:28. 161, 6495-6536 / com. Wangyz. Coroutines D/Coroutine: IO method, thread: DefaultDispatcher - 2020-09-25 23:51:29 worker - 1. 389, 6495-6537 / com wangyz. Coroutines D/Coroutine: IO method, thread: DefaultDispatcher - worker - 2 2020-09-25 23:51:29. 390, 6495-6495 / com. Wangyz. Coroutines D/Coroutine: ui method,thread:main,result:3Copy the code

Method io4 executes for 2 seconds and method io5 executes for 3 seconds. After io5 completes, their results are added and updated to UI via UI4.

reference

Developer. The android. Google. Cn/kotlin/coro…