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