android studio放置在函数上面看_Android中用Kotlin协程和Retrofit进行网络请求和取消请求...
前面兩篇文章介紹了協(xié)程的一些基本概念和基本知識,這篇則介紹在Android中如何使用協(xié)程配合Retrofit發(fā)起網(wǎng)絡請求,同時介紹在使用協(xié)程時如何優(yōu)雅的取消已經(jīng)發(fā)起的網(wǎng)絡請求。
需要文章中demo完整代碼的同學可以私我。
創(chuàng)建CoroutineScope
在前面的文章中我寫到CoroutineScope.launch方法是一個很常用的協(xié)程構建器。因此使用協(xié)程必須先得創(chuàng)建一個CoroutineScope對象,代碼如下:
CoroutineScope(Dispatchers.Main + Job())上面的代碼創(chuàng)建了一個CoroutineScope對象,為其協(xié)程指定了在主線程中執(zhí)行,同時分配了一個Job
在demo中我使用的是MVP模式寫的,所以我將CoroutineScope的創(chuàng)建放到了BasePresenter中,代碼如下:
使用CoroutineScope.cancel()取消協(xié)程
大家應該可以看到上面BasePresenter.detachView中調(diào)用了presenterScope.cancel(),那這個方法有什么作用呢,作用就是取消掉presenterScope創(chuàng)建的所有協(xié)程和其子協(xié)程。
前面的文章我也介紹過使用launch創(chuàng)建協(xié)程時會返回一個Job對象,通過Job對象的cancel方法也可以取消該任務對應的協(xié)程,那我這里為什么不使用這種方式呢?
很明顯,如果使用Job.cancel()方式取消協(xié)程,那我創(chuàng)建每個協(xié)程的時候都必須保存返回的Job對象,然后再去取消,顯然要更復雜點,而使用CoroutineScope.cancel()則可以一次性取消該協(xié)程上下文創(chuàng)建的所有協(xié)程和子協(xié)程,該代碼也可以很方便的提取到基類中,這樣后面在寫業(yè)務代碼時也就不用關心協(xié)程與View的生命周期的問題。
其實大家看源碼的話也可以發(fā)現(xiàn)CoroutineScope.cancel()最終使用的也是Job.cancel()取消協(xié)程
擴展Retrofit.Call適配協(xié)程
大家可以看到上面的api接口定義應該很熟悉,我們可以通過下面的代碼發(fā)起異步網(wǎng)絡請求
前面的文章介紹過協(xié)程可以讓異步代碼像寫同步代碼那樣方便,那上面這段異步代碼能不能使用協(xié)程改造成類似寫同步代碼塊那樣呢?很顯然是可以的,具體改造代碼如下:
上面的代碼擴展了一個掛起函數(shù)await,執(zhí)行該方法時,會執(zhí)行Retrofit.Call的異步請求同時在協(xié)程中掛起該函數(shù),直到異步請求成功或者出錯再重新恢復所在協(xié)程。
suspendCoroutine
全局函數(shù),此函數(shù)可以獲取當前方法所在協(xié)程上下文,并將當前協(xié)程掛起,直到某個時機再重新恢復協(xié)程執(zhí)行,但是這個時機其實是由開發(fā)者自己控制的,就像上面代碼中的it.resume和it.resumeWithException。
發(fā)起請求,寫法一
從上面的代碼大家可以發(fā)現(xiàn),協(xié)程中對異常的處理使用的是try-catch的方式,初學,我也暫時只想到了這種方式。所以在使用協(xié)程時,最好在業(yè)務的適當?shù)胤绞褂胻ry-catch捕獲異常,否則一旦協(xié)程執(zhí)行出現(xiàn)異常,程序就崩掉了。
另外上面的代碼的寫法還有一個問題,因為掛起函數(shù)執(zhí)行時會掛起當前協(xié)程,所以上述兩個請求是依次順序執(zhí)行,因此上面的queryGanks()方法其實是耗費了兩次網(wǎng)絡請求的時間,因為請求Android列表和請求ios列表兩個請求不是并行的,所以這種寫法肯定不是最優(yōu)解。
發(fā)起請求,寫法二
下面我們再換另外一種寫法。
這種寫法與前一種寫法的區(qū)別是采用async構建器創(chuàng)建了兩個子協(xié)程分別去請求Android列表和IOS列表,同時因為async構建器執(zhí)行的時候不會掛起當前協(xié)程,所以兩個請求是并行執(zhí)行的,因此效率較上一個寫法要高很多。
發(fā)起請求,寫法三
第三個寫法就是在Retorfit的CallAdapter上做文章,通過自定義實現(xiàn)CallAdapterFactory,將api定義時的結果Call直接轉換成Deferred,這樣就可以同時發(fā)起Android列表請求和IOS列表請求,然后通過Deferred.await獲取請求結果,這種寫法是寫法一寫法二的結合。
這種寫法JakeWharton大神早已為我們實現(xiàn)了,大家可以在他的github中搜索retrofit2-kotlin-coroutines-adapter
這里我就不說這種方案的具體實現(xiàn)了,感興趣的同學可以去看其源碼。
寫法三的具體代碼如下:
上面的第三種寫法看起來更簡潔,也是并行請求,耗時為請求時間最長的那個請求的時間,和第二種差不多。
總結
以上是生活随笔為你收集整理的android studio放置在函数上面看_Android中用Kotlin协程和Retrofit进行网络请求和取消请求...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql server insert 锁表
- 下一篇: 删除链表重复节点 python_java