/ 今日科技快讯 /
昨日,据路透社报道,谷歌在周二被提起一项集体诉讼:被指控通过设置为“隐身”模式的谷歌浏览器跟踪用户的互联网使用,而侵犯了数百万用户的隐私。诉讼在美国加州圣何塞联邦法院提起,寻求向谷歌索赔至少50亿美元。
/ 作者简介 /
本篇文章来自catzifeng的投稿,分享了在Android中如何使用协程进行网络操作,希望对大家有所帮助!同时也感谢作者贡献的精彩文章!
catzifeng的博客地址:
https://blog.csdn.net/catzifeng
/ 前言 /
Android网络界发展至今已经出现过无数风流框架,看先祖HttpURLConnection老矣,HttpClient也早已隐退,而那android-async-http力不从心却也封刀,但江湖却还流传着它的故事,有那谷歌亲儿子volley独占中州,笑迎四面八方来客,OkHttp不慌不急,稳占其余大洲,更有它那亲爹Retrofit默默支撑着它,使得各位风骚道友能够有安稳的栖身之地。
异步界RxJava“异军” 突起,揍扁太子AsnyTask逐渐统一异步界,成为异步界的霸主,RxJava虽不闻不问网络界的是非,但是偶然的一次相遇,使得RxJava和Retrofit如胶似漆,殊不知,这是Retrofit的计谋,想要借助RxJava这个工具人,壮大自己的实力,进一步统一网络界!
又不知过了多少年岁,天地宇宙各界各地突然出现崩塌迹象,无端出现莫名其妙的裂缝!裂缝每时每刻都在将每片区域空气中的Java吸走!十分霸道!各界每位风骚道友都人心惶惶,没有了Java,道友们就不能够呼吸,正当道友们岌岌可危之时,那些裂缝竟然反吐一种令人心旷神怡的气体——Kotlin,道友们呼吸到Kotlin之后,神宁瞬间安静,甚至表情中都泛有一丝春光!大家逐渐都爱上了这个新的气体。他们还发现,在练功时如果使用Kotlin, 每个大周天提炼的灵力竟然比使用Java多出一倍有余!
不仅仅是各位道友注意到了Kotlin的神奇之处,想那妖艳贱货Retrofit也早就领会Kotlin之妙用,终有一天,Retrofit不满RxJava花心浪荡,摔杯举剑,只见那秀剑飞起,在手中720度托马斯回旋,“撕拉”一声,割袍断义,与 RxJava 分道扬镳……
/ Kotlin协程 /
在Kotlin 1.3版本中 协程 逐步稳定,我们可以放心大胆的使用,关于 协程 的概念和使用详解,我无法做出太多介绍,这东西太玄学了,因为没有开放源码,江湖上没有几个道友能够彻底理解,或许也只有几位不出世的高人才能够熟知吧。
协程官方文档:
https://www.kotlincn.net/docs/reference/coroutines/coroutines-guide.html
协程可看作是一个轻量级的线程,协程必须依附在某个线程,类似于守护线程,当协程依附的线程被干掉(或者正常结束),那么这个协程也会挂掉。
/ 协程和Retrofit /
关于Retrofit如何使用,道友们肯定很是熟知:
interface ApiService{
@GET("url/request")
fun doRequest():Call
}
fun main() {
Retrofit.Builder().build() //这 里 只 是 意 思 意 思 一 下 ! ! !
.create(ApiService::class.java)
.doRequest()
.enqueue(object : Callback {
override fun onFailure(call: Call, t: Throwable) { }
override fun onResponse(call: Call, response: Response) { }
})
}
在2019年2月16号 ,大神JakeWharton对Retrofit提交了一个重要的代码:
支持了协程!当我们点进去的时候,可以看看关键的文件和代码。一个名叫KotlinExtensions.kt的文件增加了3个Kotlin扩展方法。
这3个方法就是用来配合协程一起来搞骚操作的。如果道友们因为种种原因,不能更新Retrofit比较新的版本,那么可以尝试自己去复制这几个方法到自己的扩展函数中。
GitHub地址:
https://github.com/square/retrofit/commit/b761518aa174c7b0512b73f2fe70e2e908f24081#diff-afbee4f0294010620954bfa945075192
/ 预备工作 /
如上一小节所述,如果你没法更新Retrofit ,那么你就在自己的扩展文件中添加一个扩展方法即可,这3个方法没必要都写上去,他们的本质都是一样的,所以我们只要挑选一个基本款车型即可,然后随你怎么加装配件都行:
/**
* 某 KtExtension.kt 文件
*/
suspend fun Call.await(): Response {
return suspendCancellableCoroutine { continuation ->
//车况异常处理装置
continuation.invokeOnCancellation {
cancel()
}
enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
//1.基本款装置
continuation.resume(response)
//2.加装改款胎压检测装置 <需替换基本款装置>
if (response.isSuccessful) {
continuation.resume(response.body())
} else {
continuation.resumeWithException(HttpException(response))
}
}
override fun onFailure(call: Call, t: Throwable) {
//道路异常处理装置
continuation.resumeWithException(t)
}
})
}
}
我们先导入Android的协程扩展:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5'
这样我们就能够轻松拿到主线程的协程上下文环境。
编写全局(或者局部,随你心情定)协程代码块方法:
/**
* 某 KtExtension.kt 文件
* 默认主线程的协程
*/
fun launch(block: suspend (CoroutineScope) -> Unit,
error: ((e: Exception) -> Unit)? = null,
context: CoroutineContext = Dispatchers.Main): Job {
return GlobalScope.launch(context + CoroutineExceptionHandler { _, e ->
Log.e("==>coroutineException", e.message) //1
}) {
try {
block(this)
} catch (e: Exception) { //2
Log.e("==>coroutineError", e.message)
if (error != null) {
error(e)
}
}
}
}
注意上面有两个异常捕获:1. 捕获整个协程的异常;2.捕获协程代码块执行的异常。为了保证程序的稳定,两个都必须要有。
/ 使用 /
先定义请求接口
interface LoginApi {
/**
* 获取登录二维码
*/
@GET("/xxx/xxx/xxx")
fun getLoginQRBitmap(): Call>
}
创建协程作用域
因为是全局方法,所以在哪里我们都能够调用
launch({
//MainNet.server()是封装了Retrofit的过程,此过程就不展示了
val bitmapEntity = MainNet.server(LoginApi::class.java).getLoginQRBitmap().await()
println("二维码地址为:${bitmapEntity.data}")
//加载二维码,可以进行更新 UI 的操作
initBitmap(bitmapEntity.data)
}, {
//TODO 网络请求异常处理
})
控制中断协程
launch这个方法会返回一个Job,这个Job就相当于RxJava的Disposable,可以调用其方法进行中断协程:
val job = launch({
... ...
})
//中断协程
job.cancel()
简单说明
因为是依附在主线程的协程,所以你 完全可以在launch的作用域中更新UI,又因为是协程,所以网络请求的这个过程中你完全不必当心会阻塞UI线程。
/ 总结 /
Kotlin的协程还有诸多骚操作,各位道友自行挖掘,一定会挖到珍宝仙器。(这么骚的操作,你不准备点个赞吗?)
推荐阅读:
这本《第三行代码》,让大家久等了!
我新开发了一个特别好用的开源库
时隔两年,LitePal终于又更新了!
欢迎关注我的公众号
学习技术或投稿
长按上图,识别图中二维码即可关注