用Kotlin的方式来处理网络异常

640?wx_fmt=jpeg


一. 前言

之前的文章 RxJava处理业务异常的几种方式 曾经介绍过 Retrofit 的异常可以有多种处理方式。

其中,可以使用 RxJava 的错误处理操作符,它们是专门用来处理异常的。

随便例举两个操作符:

onErrorReturn 操作符,表示当发生错误的时候,发射一个默认值然后结束数据流。所以 Subscriber 看不到异常信息,看到的是正常的数据流结束状态。

onErrorResumeNext 操作符,表示当错误发生的时候,使用另外一个数据流继续发射数据。在返回的被观察者中是看不到错误信息的。

二. 使用 Kotlin 的特性

这次我结合 Kotlin 扩展函数的特性来尝试处理异常。

网络请求返回的 Response 大多是采用如下这种形式:

 
 
  1. {

  2.   "code":0,

  3.   "message":"success",

  4.   "data":{

  5.       ...

  6.    }

  7. }

对于客户端开发而言,我们会封装一个基类的HttpResponse。

 
 
  1. data class HttpResponse<T>(

  2.        var code: Int = -1, //0: 成功 1: xxx错误或过期 2: 业务逻辑错误 500:系统内部错误 998表示Token无效

  3.        var message: String? = null,

  4.        var data: T? = null

  5. ) : UnProguard {

  6.    val isOkStatus: Boolean

  7.        get() = code == 0

  8. }

其中,UnProguard是一个空的接口,主要是方便 App 在混淆的时候保留部分类。

 
 
  1. interface UnProguard : Serializable

通常情况下,我们会在 Observer 的 onError 中按照如下的方式处理异常:

 
 
  1.        viewModel.getHelps(this)

  2.                .subscribe({

  3.                    if (it.isOkStatus) {

  4.                        multi_status_view.showContent()

  5.                        adapter.addData(it.data?.list)

  6.                    } else {

  7.                        multi_status_view.showError()

  8.                    }

  9.                }, { multi_status_view.showError() })

如果我们利用 RxJava 的错误处理操作符,可以编写如下的扩展函数:

 
 
  1. import com.safframework.utils.RetryWithDelay

  2. import io.reactivex.Maybe

  3. /**

  4. *

  5. * @FileName:

  6. *          cn.magicwindow.core.ext.`Maybe+Extension`.kt

  7. * @author: Tony Shen

  8. * @date: 2018-07-19 17:31

  9. * @version V1.0 <描述当前版本功能>

  10. */

  11. /**

  12. * 尝试重试

  13. * 默认有3次重试机会,每次的延迟时间是1000ms

  14. */

  15. fun <T> Maybe<T>.retryWithDelayMillis(maxRetries: Int=3, retryDelayMillis: Int=1000): Maybe<T> =

  16.        this.retryWhen(RetryWithDelay(maxRetries,retryDelayMillis))

  17. /**

  18. * 遇到错误时,能够提前捕获异常,并发射一个默认的值。

  19. * 后面无须再做异常处理

  20. */

  21. fun <T> Maybe<T>.errorReturn(defValue:T): Maybe<T> = this.onErrorReturn {

  22.    it -> it.printStackTrace()

  23.    return@onErrorReturn defValue

  24. }

  25. fun <T> Maybe<T>.errorReturn(defValue:T,action: (Throwable) -> Unit): Maybe<T> = this.onErrorReturn {

  26.    action.invoke(it)

  27.    return@onErrorReturn defValue

  28. }

  29. /**

  30. * 遇到错误时,能够提前捕获异常,并返回一个新的Maybe

  31. * 后面无须再做异常处理

  32. */

  33. fun <T> Maybe<T>.errorResumeNext(defValue:T):Maybe<T> = this.onErrorResumeNext(Maybe.just(defValue))

  34. fun <T> Maybe<T>.errorResumeNext():Maybe<T> = this.onErrorResumeNext(Maybe.empty())

扩展函数 errorReturn 的使用:

 
 
  1.        viewModel.getHelps(this)

  2.                .errorReturn(HttpResponse()) {

  3.                    multi_status_view.showError()

  4.                }

  5.                .subscribe{

  6.                    if (it.isOkStatus) {

  7.                        multi_status_view.showContent()

  8.                        adapter.addData(it.data?.list)

  9.                    } else {

  10.                        multi_status_view.showError()

  11.                    }

  12.                }

这样无须在 onError 中处理异常,而且 errorReturn 还是一个高阶函数。它的 action 参数传递的是一个函数,专门用于处理异常。每一个网络请求的异常处理并不会都一样,可以用该函数来传递不同的异常处理。

总结

合理利用 Kotlin 的扩展函数,可以编写优雅的代码。而使用高阶函数,则可以达到的进一步的抽象。



关注【Java与Android技术栈】

更多精彩内容请关注扫码

640?wx_fmt=jpeg


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值