日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

超简单-用协程简化你的网络请求吧,兼容你的老项目和旧的网络请求方式

發布時間:2025/3/21 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 超简单-用协程简化你的网络请求吧,兼容你的老项目和旧的网络请求方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

在Kotlin協程(后簡稱協程)出來之后,顛覆了我們很多工具類的封裝方式,大大簡化了我們很多api的調用,并且使異步操作邏輯更清晰了

其中一個很標志性的地方就屬網絡請求了,以前的網絡請求方式聲明很麻煩,請求和響應也很麻煩,總結一句話就是啰嗦且易出錯

ps:最終的使用方式示例:

使用網絡請求的進化過程:

1.從一開始的HttpURLConnection的一把梭,直接一個請求寫一串代碼(代碼太多就不寫了)

2.到后續使用三方封裝的網絡框架,如XUtils,Volly,OkHttp等,這些雖然也簡化了操作,但也是很復雜,比如封裝了兩層的OkHttp可能還需要以下方式聲明和調用:

然后在一個或多個回調中處理返回的數據并判斷是否是請求成功,解析成響應的數據并操作

3.后來Retrofit出現,解救了苦于網絡請求太啰嗦的萬千開發們,其使用動態代理加良好的封裝,使網絡請求聲明和請求都變得更簡單了

ps:Retrofit如何使用動態代理參考:模仿Retrofit封裝一個使用更簡單的網絡請求框架_lt的博客-CSDN博客_retrofit封裝網絡請求

pps:進一步簡化Retrofit的聲明參考:更易于使用的Retrofit(不用寫注解)_lt的博客-CSDN博客

聲明如下(其會在調用的時候自動解析成一個post請求的Call對象):

使用如下:

可以發現雖然聲明簡單了很多,但使用還是比較麻煩

這時候就輪到協程登場了

正文

如果是使用Retrofit配合協程簡化網絡請求參考我以前寫的文章第二條(封裝網絡請求):Kotlin協程在項目中的實際應用_lt的博客-CSDN博客_kotlin協程使用

否則可以看下面的:

接下來就是重頭戲:用協程兼容你的老項目和舊的網絡請求方式,并且請求方式就像這張圖一樣

首先我們可以觀察一下我們的舊方式的請求,發現可能是有一個統一的回調,將服務端返回的String返回來,可能類似情況1:

?也可能使用OkHttp,類似情況2:

也可能類似情況3:

?可以觀察到,他們都是基于回調,而協程可以將回調轉成同步的掛起函數,所以我們將第三種方式(其他情況也類似),改造代碼如下:

interface BaseHttp {//網絡請求成功后調用該方法fun onHttpSuccess(data: String?)//網絡請求失敗后調用該方法fun onHttpFailed(message: String?) }/*** creator: lt lt.dygzs@qq.com* effect : 使用協程封裝基于回調的網絡請求* warning:*/ abstract class CoroutineHttp<T : Any> : BaseHttp {private var continuation: CancellableContinuation<Result>? = null//協程對象,如果getX調用慢于回調用private var result: Result? = null//響應結果,如果getX先與回調用//網絡請求成功后調用該方法 //2*********************************override fun onHttpSuccess(data: String?) {//保證線程安全handler.post {val continuation = continuationif (continuation == null) {result = Result(data, true)return@post}continuation.resume(Result(data, true))}}//網絡請求失敗后調用該方法override fun onHttpFailed(message: String?) {handler.post {val continuation = continuationif (continuation == null) {result = Result(message, false)return@post}continuation.resume(Result(message, false))}}/*** 檢查協程網絡請求的返回值和當前狀態是否符合要求* 如果不符合要求,會回調失敗的接口,并返回null,不會取消當前協程* [errorListener]msg:服務端返回的消息或異常信息,如果不傳使用默認失敗策略(即彈toast)*/ //1*********************************suspend fun getOrNull(errorListener: (msg: String?) -> Unit = HttpErrorListener): T? {//保證線程安全val json = withContext(Dispatchers.Main) {val result = suspendCancellableCoroutine<Result> { continuation ->val result = resultif (result != null) { //4*********************************continuation.resume(result)return@suspendCancellableCoroutine}this@CoroutineHttp.continuation = continuation} //3*********************************return@withContext if (result.isSuccess) result.data else {errorListener(result.data)null}}return withContext(Dispatchers.Default) {Gson().fromJson(json,this@CoroutineHttp.getSuperClassTypes().first())}}/*** 檢查協程網絡請求的返回值和當前狀態是否符合要求* 如果不符合要求,會回調失敗的接口,并取消當前協程* [errorListener]msg:服務端返回的消息或異常信息,如果不傳使用默認失敗策略(即彈toast)*/suspend fun get(errorListener: (String?) -> Unit = HttpErrorListener): T =getOrNull(errorListener) ?: cancelAndThrow()//獲取協程數據,并自動顯示和隱藏彈窗,并自動轉換成響應類型,如果請求失敗或轉換失敗則返回nullsuspend fun getOrNullWithDialog(errorListener: (String?) -> Unit = HttpErrorListener): T? {val baseActive = coroutineContext[CoroutineElementWithBaseActive]?.baseActivebaseActive?.showWaitDialog()try {return getOrNull(errorListener)} finally {baseActive?.dismissWaitDialog()}}// 獲取協程數據,并自動顯示和隱藏彈窗,并自動轉換成響應類型,如果請求失敗或轉換失敗則取消協程suspend fun getWithDialog(errorListener: (String?) -> Unit = HttpErrorListener): T =getOrNullWithDialog(errorListener) ?: cancelAndThrow()class Result(val data: String?, val isSuccess: Boolean)private object HttpErrorListener : (String?) -> Unit {override fun invoke(p1: String?) {p1.showToast()}}/*** 取消并拋出異常*/suspend fun cancelAndThrow(): Nothing = coroutineContext.job.cancelAndThrow()/*** 獲取super的泛型的type列表*/ fun Any.getSuperClassTypes(): Array<Type> =this::class.java.genericSuperclass.asT<ParameterizedType>().actualTypeArguments }private val handler = Handler(Looper.getMainLooper())

原理大致就是將協程內部的回調給保存下來(掛起),然后在適當的時間調用協程的resume使協程恢復執行

可以看代碼標識1處,其他的getxxx方法都會走到這個getOrNull方法中,其先調用suspendCancellableCoroutine方法將協程掛起并拿到內部的回調

然后再看代碼標識2處,網絡請求回調成功后會走這個onHttpSuccess方法,然后我們判斷是否已經掛起了協程(注冊了協程的回調):

? ? 1.如果掛起了,就調用resume恢復協程的運行,此時代碼會執行到標識3處,且將result傳了過去,然后后續就執行解析json并判斷是否成功等耦合項目的邏輯

? ? 2.如果沒有掛起,就將數據保存在類中,然后會在調用getxxx方法時檢測到有數據并直接恢復協程(標識4處)

然后比如網絡請求這樣聲明:

最后我們就可以使用協程請求網絡了(紅框的位置相當于getWithDialog方法的成功回調):

?也可以在方法后面傳入回調處理請求失敗的情況(紅框位置是成功的回調,黃框位置是失敗的回調):

?使用協程和gson解析需要導入以下的依賴:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'implementation 'com.google.code.gson:gson:2.8.7'

擴展

1.CoroutineHttp為什么要聲明為抽象類?

因為jvm的泛型擦除,如果你不創建出新的Class,就無法獲取他設置的泛型的Type,而使用抽象類,你每new一個匿名內部類都會創建出一個Class,所以可以通過反射獲取其聲明的泛型的Type

當然open class也可以寫出匿名內部類,但是沒有了硬性規定容易出現遺漏導致出現bug

2.mainScope是什么

mainScope是一個自定義的協程作用域(CoroutineScope),創建它可以參考這一篇Kotlin-如何創建一個好用的協程作用域_lt的博客-CSDN博客

一般在activity中需要在onCreate中創建,在onDestroy中調用cancel()來取消它所有啟動的協程

如果在fragment中就在onCreate中創建,在onDestroyView中調用cancel()

如果有疑問可以評論區留言

end

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的超简单-用协程简化你的网络请求吧,兼容你的老项目和旧的网络请求方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: chinese麻豆新拍video | 久久九九国产视频 | 欧美肥老妇 | 国产主播啪啪 | 国产美女免费网站 | 精品一性一色一乱农村 | 久久久社区| 性色在线视频 | 一卡二卡国产 | 中文字幕av一区二区三区人妻少妇 | 国产一线二线三线女 | 国产激情视频一区 | 久久精品三级视频 | 日韩欧美一区二区三区久久婷婷 | 日韩成人综合 | 一区二区在线视频观看 | av成人亚洲 | 伊人开心网 | 精品亚洲国产成人av制服丝袜 | 韩日视频 | 精品人妻一区二区免费视频 | 精品蜜桃av| 婷婷丁香色 | 六月婷婷久久 | 无码人妻精品一区二区三区66 | 亚洲天堂网一区 | 免费在线观看av片 | 人妻一区二区三区四区 | 性色av一区二区 | 性xxxx另类xxⅹ | 性感美女在线观看 | 少妇粉嫩小泬喷水视频www | 欧美精品免费一区二区三区 | 免费日本黄色网址 | 日韩激情床戏 | 一二三区中文字幕 | 五月天婷婷色综合 | 日本女优黄色 | 亚洲高清视频在线观看 | 精品人妻一区二区三区日产 | 五月天天色 | 后进极品美女圆润翘臀 | 中文字幕亚洲在线观看 | 免费看三级黄色片 | 午夜综合网 | 久久激情免费视频 | 欧美91视频 | 自拍视频一区 | 日韩一卡 | 免费jizz | 97精品一区二区视频在线观看 | 国产精品免费看片 | 中文字幕免费高 | 欧美脚交 | 三级免费黄录像 | av看片网站| 欧美精品久久久久性色 | 欧美动态色图 | 人人看超碰 | 日日噜噜夜夜狠狠久久丁香五月 | 国产乱码精品一区二区三区中文 | 蜜臀久久99精品久久久久久宅男 | 午夜免费一区二区 | 综合色av| 玖玖爱国产| 熟女丰满老熟女熟妇 | 一区二区三区激情视频 | 一级黄色片在线看 | 亚洲综合日韩精品欧美综合区 | 外国黄色网址 | 欧美精品一区二区久久婷婷 | 亚洲一在线 | 亚洲欧美日韩电影 | 欧美1314| 少妇三级 | 亚洲播播 | 国产精品玖玖玖 | 黄色免费网站在线 | 黄色网页在线 | 欧美日韩在线直播 | 手机在线看片你懂的 | 51av在线 | 日韩av在线免费播放 | 国产欧美日韩一区二区三区 | 9久9久9久女女女九九九一九 | 日韩中文字幕av在线 | 插入综合网 | 亚洲精品乱码久久久久久自慰 | 中文字幕 日韩 欧美 | 国产伦精品一区二区三区四区免费 | 视频在线国产 | 特级精品毛片免费观看 | 日韩中文字幕亚洲精品欧美 | 香蕉国产精品视频 | 久久精品国产亚洲AV无码麻豆 | 色撸撸在线视频 | 中文字幕一区二区三区电影 | 亚洲黄色片网站 | www.猫咪av |