RxJava捕获Consumer异常:Android应用网络处理优化方案咨询
我来帮你梳理下如何优化这个网络响应处理的异常捕获问题,结合你目前用RxJava+Consumer的架构,咱们一步步来调整。
首先先明确你现有代码的潜在问题:当前的NetworkConsumer继承了Consumer接口,但accept方法里如果抛出异常(比如处理NetworkResponse时的业务逻辑异常,或者response.isSuccess()判断后的分支里的异常),会直接传递到RxJava的订阅流中,可能导致整个流中断,而且异常处理的逻辑分散在各个子类里,难以统一管理。
方案1:改造NetworkConsumer基类,统一异常捕获与分层处理
我们可以把NetworkConsumer改造成一个带默认异常处理的抽象基类,将成功、业务失败、系统异常拆分成不同的抽象方法,同时在accept方法中统一捕获所有异常,避免流中断。
先看你现有的基础代码:
// 你的Consumer接口 public interface Consumer<T> { /** * Consume the given value. * @param t the value * @throws Exception on error */ void accept(T t) throws Exception; }
// 你的NetworkConsumer抽象类(补全未写完的部分) abstract class NetworkConsumer<T> : Consumer<NetworkResponse<T>> { override fun accept(response: NetworkResponse<T>) { if (response.isSuccess) { // 处理成功逻辑,但可能抛出异常 } else { // 处理失败逻辑,也可能抛出异常 } } }
改造后的NetworkConsumer:
abstract class NetworkConsumer<T> : Consumer<NetworkResponse<T>> { override fun accept(response: NetworkResponse<T>) { try { when { response.isSuccess -> response.data?.let { onSuccess(it) } ?: onEmptySuccess() else -> onFailure(response.code, response.message) } } catch (e: Exception) { // 统一捕获所有处理过程中抛出的异常 onError(e) } } /** * 处理网络响应成功且有数据的情况 */ protected abstract fun onSuccess(data: T) /** * 处理网络响应成功但无数据的情况(可选,根据你的业务需求调整) */ protected open fun onEmptySuccess() { // 默认实现可以留空,或者抛出默认异常,子类按需重写 } /** * 处理网络响应失败的情况(比如HTTP状态码非200,或者业务码错误) */ protected abstract fun onFailure(code: Int?, message: String?) /** * 统一处理所有异常(包括处理成功/失败逻辑时抛出的异常) */ protected open fun onError(e: Exception) { // 默认可以做全局异常上报,子类也可以按需重写 e.printStackTrace() // 比如这里可以接入你的异常上报SDK } }
方案2:结合RxJava操作符,增强流的容错性
除了在Consumer层捕获异常,我们还可以在RxJava的数据流链中添加错误处理操作符,形成双重保障,避免单个请求的异常影响整个订阅流:
// 示例:在网络请求的Observable链中添加错误处理 apiService.fetchData() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) // 捕获网络请求阶段的异常(比如IO异常、连接超时等) .onErrorResumeNext { throwable -> // 可以返回一个"失败"的NetworkResponse,让Consumer统一处理 Observable.just(NetworkResponse.failure(-1, throwable.message)) } .subscribe(object : NetworkConsumer<Data>() { override fun onSuccess(data: Data) { // 处理成功数据 } override fun onFailure(code: Int?, message: String?) { // 处理业务失败 } // 按需重写onError,处理异常 override fun onError(e: Exception) { super.onError(e) // 自定义异常处理逻辑 } })
额外优化建议
用密封类定义NetworkResponse:把
NetworkResponse改成密封类,让状态判断更安全,避免遗漏分支:sealed class NetworkResponse<out T> { data class Success<out T>(val data: T) : NetworkResponse<T>() data class Failure(val code: Int, val message: String) : NetworkResponse<Nothing>() object Empty : NetworkResponse<Nothing>() }这样在
NetworkConsumer的accept方法中,用when表达式可以做到穷尽匹配,减少逻辑漏洞。统一异常分类:定义自定义异常类(比如
NetworkException、BusinessException),在onError中区分不同异常类型,做针对性处理。考虑RxJava的错误传递机制:如果不需要在Consumer中捕获异常,也可以用
subscribe的重载方法(subscribe(Consumer<T>, Consumer<Throwable>)),把成功和异常处理分开,但这样不如统一基类的方式集中管理。
内容的提问来源于stack exchange,提问作者advice

