A lightweight thread

  • Old-school thread switching relies on operating system scheduling, but coroutines allow thread-free switching only at the programming language level

  • Introduce the coroutine library

Implementation 'org. Jetbrains. Kotlinx: kotlinx coroutines -- core: 1.3.0' implementation 'org. Jetbrains. Kotlinx: kotlinx coroutines - android: 1.1.1'Copy the code
  • Override Retrofit library callback methods using coroutines
package com.example.androidnetworkdemo.retrofit

import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.lang.RuntimeException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

object ServiceCreator {

    private const val BASE_URL = "http://10.0.0.1"
    private val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)

    inline fun <reified T> create(a): T = create(T::class.java)

    / / coroutines
    suspend fun <T> Call<T>.await(a): T {
        return suspendCoroutine { continuation ->
            enqueue(object : Callback<T> {
                override fun onFailure(call: Call<T>, t: Throwable) {
                    continuation.resumeWithException(t)
                }

                override fun onResponse(call: Call<T>, response: Response<T>) {
                    val body = response.body()
                    if(body ! =null) continuation.resume(body)
                    else continuation.resumeWithException(
                            RuntimeException("response body is null"))}})}}}Copy the code
  • To use it, just like writing synchronous code, the next suspend function can be used
/ / coroutines
    suspend fun getAppData(a) {
        try {
            val appList = ServiceCreator.create<AppService>().getAppData().await()
        } catch (e: Exception) {

        }
    }

    / / not coroutines
    private fun retrofit(a) {

        val appService = ServiceCreator.create<AppService>()
        appService.getAppData().enqueue(object : Callback<List<App>> {
            override fun onFailure(call: Call<List<App>>, t: Throwable) {
                t.printStackTrace()
            }

            override fun onResponse(call: Call<List<App>>, response: Response<List<App> >) {
                val list = response.body()
                if(list ! =null) {
                    for (app in list) {
                        Log.d("tag", app.id + app.name + app.version)
                    }
                }
            }
        })
    }
Copy the code