一种轻量级的线程
-
古老的线程切换需要依赖操作系统的调度,但是协程仅在编程语言的层面就实现了不用线程的切换
-
引入协程库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
- 使用协程重写Retrofit库的回调方法
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(): T = create(T::class.java)
// 协程
suspend fun <T> Call<T>.await(): 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")
)
}
})
}
}
}
- 使用起来,就像写同步代码一样,下一个挂起函数即可
// 协程
suspend fun getAppData() {
try {
val appList = ServiceCreator.create<AppService>().getAppData().await()
} catch (e: Exception) {
}
}
// 非协程
private fun retrofit() {
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)
}
}
}
})
}