利用Kotlin的方式如何處理網(wǎng)絡(luò)異常詳解
一. 前言
之前的文章 RxJava處理業(yè)務(wù)異常的幾種方式 曾經(jīng)介紹過 Retrofit 的異常可以有多種處理方式。
其中,可以使用 RxJava 的錯誤處理操作符,它們是專門用來處理異常的。
隨便例舉兩個操作符:
onErrorReturn 操作符,表示當(dāng)發(fā)生錯誤的時候,發(fā)射一個默認值然后結(jié)束數(shù)據(jù)流。所以 Subscriber 看不到異常信息,看到的是正常的數(shù)據(jù)流結(jié)束狀態(tài)。
onErrorResumeNext 操作符,表示當(dāng)錯誤發(fā)生的時候,使用另外一個數(shù)據(jù)流繼續(xù)發(fā)射數(shù)據(jù)。在返回的被觀察者中是看不到錯誤信息的。
二. 使用 Kotlin 的特性
這次我結(jié)合 Kotlin 擴展函數(shù)的特性來嘗試處理異常。
網(wǎng)絡(luò)請求返回的 Response 大多是采用如下這種形式:
{ "code":0, "message":"success", "data":{ ... } }
對于客戶端開發(fā)而言,我們會封裝一個基類的HttpResponse。
data class HttpResponse<T>( var code: Int = -1, //0: 成功 1: xxx錯誤或過期 2: 業(yè)務(wù)邏輯錯誤 500:系統(tǒng)內(nèi)部錯誤 998表示Token無效 var message: String? = null, var data: T? = null ) : UnProguard { val isOkStatus: Boolean get() = code == 0 }
其中,UnProguard是一個空的接口,主要是方便 App 在混淆的時候保留部分類。
interface UnProguard : Serializable
通常情況下,我們會在 Observer 的 onError 中按照如下的方式處理異常:
viewModel.getHelps(this) .subscribe({ if (it.isOkStatus) { multi_status_view.showContent() adapter.addData(it.data?.list) } else { multi_status_view.showError() } }, { multi_status_view.showError() })
如果我們利用 RxJava 的錯誤處理操作符,可以編寫如下的擴展函數(shù):
import com.safframework.utils.RetryWithDelay import io.reactivex.Maybe /** * * @FileName: * cn.magicwindow.core.ext.`Maybe+Extension`.kt * @author: Tony Shen * @date: 2018-07-19 17:31 * @version V1.0 <描述當(dāng)前版本功能> */ /** * 嘗試重試 * 默認有3次重試機會,每次的延遲時間是1000ms */ fun <T> Maybe<T>.retryWithDelayMillis(maxRetries: Int=3, retryDelayMillis: Int=1000): Maybe<T> = this.retryWhen(RetryWithDelay(maxRetries,retryDelayMillis)) /** * 遇到錯誤時,能夠提前捕獲異常,并發(fā)射一個默認的值。 * 后面無須再做異常處理 */ fun <T> Maybe<T>.errorReturn(defValue:T): Maybe<T> = this.onErrorReturn { it -> it.printStackTrace() return@onErrorReturn defValue } fun <T> Maybe<T>.errorReturn(defValue:T,action: (Throwable) -> Unit): Maybe<T> = this.onErrorReturn { action.invoke(it) return@onErrorReturn defValue } /** * 遇到錯誤時,能夠提前捕獲異常,并返回一個新的Maybe * 后面無須再做異常處理 */ fun <T> Maybe<T>.errorResumeNext(defValue:T):Maybe<T> = this.onErrorResumeNext(Maybe.just(defValue)) fun <T> Maybe<T>.errorResumeNext():Maybe<T> = this.onErrorResumeNext(Maybe.empty())
擴展函數(shù) errorReturn 的使用:
viewModel.getHelps(this) .errorReturn(HttpResponse()) { multi_status_view.showError() } .subscribe{ if (it.isOkStatus) { multi_status_view.showContent() adapter.addData(it.data?.list) } else { multi_status_view.showError() } }
這樣無須在 onError 中處理異常,而且 errorReturn 還是一個高階函數(shù)。它的 action 參數(shù)傳遞的是一個函數(shù),專門用于處理異常。每一個網(wǎng)絡(luò)請求的異常處理并不會都一樣,可以用該函數(shù)來傳遞不同的異常處理。
總結(jié)
合理利用 Kotlin 的擴展函數(shù),可以編寫優(yōu)雅的代碼。而使用高階函數(shù),則可以達到的進一步的抽象。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
Android高德地圖poi檢索仿微信發(fā)送位置實例代碼
本篇文章主要介紹了Android高德地圖poi檢索仿微信發(fā)送位置實例代碼,具有一定的參考價值,有興趣的可以了解一下。2017-04-04Android跳轉(zhuǎn)到系統(tǒng)聯(lián)系人及撥號或短信界面
現(xiàn)在開發(fā)中的功能需要直接跳轉(zhuǎn)到撥號、聯(lián)系人、短信界面等等,查找了很多資料,自己整理了一下特此分享到腳本之家平臺供大家參考2016-12-12Jetpack?Compose?實現(xiàn)一個圖片選擇框架功能
這篇文章主要介紹了Jetpack?Compose?實現(xiàn)一個圖片選擇框架,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06