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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

android studio放置在函数上面看_Android中用Kotlin协程和Retrofit进行网络请求和取消请求...

發(fā)布時(shí)間:2025/3/21 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android studio放置在函数上面看_Android中用Kotlin协程和Retrofit进行网络请求和取消请求... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前面兩篇文章介紹了協(xié)程的一些基本概念和基本知識(shí),這篇?jiǎng)t介紹在Android中如何使用協(xié)程配合Retrofit發(fā)起網(wǎng)絡(luò)請(qǐng)求,同時(shí)介紹在使用協(xié)程時(shí)如何優(yōu)雅的取消已經(jīng)發(fā)起的網(wǎng)絡(luò)請(qǐng)求。

需要文章中demo完整代碼的同學(xué)可以私我。

創(chuàng)建CoroutineScope

在前面的文章中我寫到CoroutineScope.launch方法是一個(gè)很常用的協(xié)程構(gòu)建器。因此使用協(xié)程必須先得創(chuàng)建一個(gè)CoroutineScope對(duì)象,代碼如下:

CoroutineScope(Dispatchers.Main + Job())

上面的代碼創(chuàng)建了一個(gè)CoroutineScope對(duì)象,為其協(xié)程指定了在主線程中執(zhí)行,同時(shí)分配了一個(gè)Job

在demo中我使用的是MVP模式寫的,所以我將CoroutineScope的創(chuàng)建放到了BasePresenter中,代碼如下:

使用CoroutineScope.cancel()取消協(xié)程

大家應(yīng)該可以看到上面BasePresenter.detachView中調(diào)用了presenterScope.cancel(),那這個(gè)方法有什么作用呢,作用就是取消掉presenterScope創(chuàng)建的所有協(xié)程和其子協(xié)程。

前面的文章我也介紹過使用launch創(chuàng)建協(xié)程時(shí)會(huì)返回一個(gè)Job對(duì)象,通過Job對(duì)象的cancel方法也可以取消該任務(wù)對(duì)應(yīng)的協(xié)程,那我這里為什么不使用這種方式呢?

很明顯,如果使用Job.cancel()方式取消協(xié)程,那我創(chuàng)建每個(gè)協(xié)程的時(shí)候都必須保存返回的Job對(duì)象,然后再去取消,顯然要更復(fù)雜點(diǎn),而使用CoroutineScope.cancel()則可以一次性取消該協(xié)程上下文創(chuàng)建的所有協(xié)程和子協(xié)程,該代碼也可以很方便的提取到基類中,這樣后面在寫業(yè)務(wù)代碼時(shí)也就不用關(guān)心協(xié)程與View的生命周期的問題。

其實(shí)大家看源碼的話也可以發(fā)現(xiàn)CoroutineScope.cancel()最終使用的也是Job.cancel()取消協(xié)程

擴(kuò)展Retrofit.Call適配協(xié)程

大家可以看到上面的api接口定義應(yīng)該很熟悉,我們可以通過下面的代碼發(fā)起異步網(wǎng)絡(luò)請(qǐng)求

前面的文章介紹過協(xié)程可以讓異步代碼像寫同步代碼那樣方便,那上面這段異步代碼能不能使用協(xié)程改造成類似寫同步代碼塊那樣呢?很顯然是可以的,具體改造代碼如下:

上面的代碼擴(kuò)展了一個(gè)掛起函數(shù)await,執(zhí)行該方法時(shí),會(huì)執(zhí)行Retrofit.Call的異步請(qǐng)求同時(shí)在協(xié)程中掛起該函數(shù),直到異步請(qǐng)求成功或者出錯(cuò)再重新恢復(fù)所在協(xié)程。

suspendCoroutine

全局函數(shù),此函數(shù)可以獲取當(dāng)前方法所在協(xié)程上下文,并將當(dāng)前協(xié)程掛起,直到某個(gè)時(shí)機(jī)再重新恢復(fù)協(xié)程執(zhí)行,但是這個(gè)時(shí)機(jī)其實(shí)是由開發(fā)者自己控制的,就像上面代碼中的it.resume和it.resumeWithException。

發(fā)起請(qǐng)求,寫法一

從上面的代碼大家可以發(fā)現(xiàn),協(xié)程中對(duì)異常的處理使用的是try-catch的方式,初學(xué),我也暫時(shí)只想到了這種方式。所以在使用協(xié)程時(shí),最好在業(yè)務(wù)的適當(dāng)?shù)胤绞褂胻ry-catch捕獲異常,否則一旦協(xié)程執(zhí)行出現(xiàn)異常,程序就崩掉了。

另外上面的代碼的寫法還有一個(gè)問題,因?yàn)閽炱鸷瘮?shù)執(zhí)行時(shí)會(huì)掛起當(dāng)前協(xié)程,所以上述兩個(gè)請(qǐng)求是依次順序執(zhí)行,因此上面的queryGanks()方法其實(shí)是耗費(fèi)了兩次網(wǎng)絡(luò)請(qǐng)求的時(shí)間,因?yàn)檎?qǐng)求Android列表和請(qǐng)求ios列表兩個(gè)請(qǐng)求不是并行的,所以這種寫法肯定不是最優(yōu)解。

發(fā)起請(qǐng)求,寫法二

下面我們?cè)贀Q另外一種寫法。

這種寫法與前一種寫法的區(qū)別是采用async構(gòu)建器創(chuàng)建了兩個(gè)子協(xié)程分別去請(qǐng)求Android列表和IOS列表,同時(shí)因?yàn)閍sync構(gòu)建器執(zhí)行的時(shí)候不會(huì)掛起當(dāng)前協(xié)程,所以兩個(gè)請(qǐng)求是并行執(zhí)行的,因此效率較上一個(gè)寫法要高很多。

發(fā)起請(qǐng)求,寫法三

第三個(gè)寫法就是在Retorfit的CallAdapter上做文章,通過自定義實(shí)現(xiàn)CallAdapterFactory,將api定義時(shí)的結(jié)果Call直接轉(zhuǎn)換成Deferred,這樣就可以同時(shí)發(fā)起Android列表請(qǐng)求和IOS列表請(qǐng)求,然后通過Deferred.await獲取請(qǐng)求結(jié)果,這種寫法是寫法一寫法二的結(jié)合。

這種寫法JakeWharton大神早已為我們實(shí)現(xiàn)了,大家可以在他的github中搜索retrofit2-kotlin-coroutines-adapter

這里我就不說這種方案的具體實(shí)現(xiàn)了,感興趣的同學(xué)可以去看其源碼。

寫法三的具體代碼如下:

上面的第三種寫法看起來更簡(jiǎn)潔,也是并行請(qǐng)求,耗時(shí)為請(qǐng)求時(shí)間最長(zhǎng)的那個(gè)請(qǐng)求的時(shí)間,和第二種差不多。

總結(jié)

以上是生活随笔為你收集整理的android studio放置在函数上面看_Android中用Kotlin协程和Retrofit进行网络请求和取消请求...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。