The foreword 0.

Coroutines previously been Kotlin as a library of experimental, the other day found the 1.3 version of the Kotlin relese the coroutines, so find time to study, would have wanted to write this article originally, but because of my departure for work, hasn’t begun, this two days finally got out, the record I some understanding of coroutines.

1. What is a coroutine

1.1 Coroutine definition

Is my first contact with coroutines in python tutorial, then Liao Xuefeng among them is “A good explanation brought here to explain: subroutines, or A function is called, is call hierarchy in all languages, such as A call to B, B in the process of execution and invoke the C, C complete return, return B has been completed, the final is A complete. So subroutine calls are implemented through the stack, and a thread is executing a subroutine. Subroutine calls are always one entry, one return, and the order of calls is clear. Coroutine calls are different from subroutines. Coroutines also appear to be subroutines, but during execution, can be interrupted within the subroutine, and then turn to execute another subroutine, and then return at the appropriate time to continue execution. Note that interrupts in one subroutine to perform other subroutines, not function calls, are similar to CPU interrupts.

If you look at the diagram, coroutines are executed sequentially in a thread. The suspension point is struck because of the suspension point. The program is suspended and the next subroutine is executed with a continuation.

1.2 Relationship between coroutines and threads

Both coroutines and threads can be used to implement asynchronous calls, but there are essential differences between the two

(1) Coroutines are at the compiler level and threads are at the system level. The switch of coroutine is controlled by the program, and the switch of thread is controlled by the operating system.

(2) Coroutines are collaborative and threads are preemptive. Coroutines are controlled by the program when to switch, while threads are controlled by the operating system to switch between threads.

(3) A thread can contain multiple coroutines.

(4) In Java, multithreading can take full advantage of multi-core CPU, coroutines are executed in a thread.

(5) Coroutines are suitable for IO intensive programs, and multithreading is suitable for computation-intensive programs (suitable for multi-core CPUS). When your application is mostly file read and write operations or operating network request, then you should be the preferred coroutines instead of multithreading, first of all, most of this operation does not use the CPU to calculate but waiting for data reading and writing, and second because coroutines execution efficiency is higher, subroutine is not thread switches, switch is controlled by the program itself, therefore, no thread overhead, The greater the number of threads, the greater the performance advantage of coroutines over multithreading. (6) Use coroutines to call asynchronous code sequentially, avoiding callback hell.

2. Simple usage

Here I’m going to simulate a network request, click on the Button to send the network request, show a Progressbar spinning around, return the result and then a TextView shows the result and hides the Progressbar. Let’s look at the layout file

<? xml version="1.0" encoding="utf-8"? > <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <TextView
            android:id="@+id/timeTV"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    <Button
            android:id="@+id/sendBT"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="SEND"
            android:layout_gravity="center"/>
    <ProgressBar
            android:layout_gravity="center"
            android:visibility="gone"
            android:id="@+id/loadingPB"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

</FrameLayout>
Copy the code

A Button, a TextView, and a ProgressBar

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sendBT.setOnClickListener {

            coroutineSend()

        }
    }

    private fun coroutineSend() {
        val uiScope = CoroutineScope(Dispatchers.Main)
        uiScope.launch {
            loadingPB.visibility = View.VISIBLE
            val deffer = async(Dispatchers.Default) {
                getCoroutineResult()
            }
            val coroutineResult = deffer.await()
            timeTV.text = "get $coroutineResult"
            loadingPB.visibility = View.GONE
        }

    }

    private suspend fun getCoroutineResult(): String {

        delay(9000L)
        return "coroutine result"}}Copy the code

First, a CoroutineScope is created, in which all coroutines run, and the CoroutineScop is created with the parameter Dispatchers.Main, which is a coroutine scheduler, which determines that the corresponding coroutine uses one or more threads for execution. The coroutine scheduler can restrict execution of a coroutine to a given thread, schedule it to run in a thread pool, or let it run unrestricted. Call launch, and you start a coroutine. The launch method returns a job. Call cancel to cancel the coroutine. As you can see in the coroutine we first show loadingPB, then call async to start another coroutine, and use the coroutine scheduler Dispatchers.Default, which will make the coroutine execute with a defaultDispatcher-worker-1 thread. The reason why async is used instead of launch is because async returns a Deferred object, and calling the await method can block the flow of execution until the coroutine finishes executing and returns the result, so you can get a return value. In this coroutine created by async, you can use the suspend method

 private suspend fun getCoroutineResult(): String {

        delay(9000L)
        return "coroutine result"
    }
Copy the code

Hibernate for 9 seconds and return a string. Note that the delay here is also a suspend method. A suspend method can only be called from a coroutine or a suspend method. There are other ways to create and use coroutines, and you can check out the official tutorial if you are interested.

3. Rxjava VS coroutines

What are the advantages of coroutines over RxJava?

(1)RxJava stack readability check, once there is a problem, the stack information explosion, difficult to locate the problem, and coroutines can avoid this problem

(2) Coroutine with synchronous way to write asynchronous code, good life, convenient code reading.

(3) Coroutine learning curve is relatively flat, compared with RxJava, coroutine is easier for beginners to learn.

4. The last

Some new features have been added to Kotlin. It’s worth learning more about. Of course, I’ll write a few articles about The Flutter, after all, I’m very optimistic about it.

Follow my official account