阿里云服务器免费领卷啦。

捡代码论坛-最全的游戏源码下载技术网站!

 找回密码
 立 即 注 册

QQ登录

只需一步,快速开始

搜索
关于源码区的附件失效或欺骗帖, 处理办法
查看: 3954|回复: 0

[安卓] Retrofit+RxJava 优雅地处理服务器返回的错误和客户端访问网络过程中产生的错误

[复制链接]

4208

主题

210

回帖

12万

积分

管理员

管理员

Rank: 9Rank: 9Rank: 9

积分
126189
QQ
发表于 2017-5-11 16:12:43 | 显示全部楼层 |阅读模式

开始本博客之前,请先阅读:
Retrofit请求数据对错误以及网络异常的处理

异常&错误

实际开发经常有这种情况,比如登录请求,接口返回的
信息包括请求返回的状态:失败还是成功,错误码,User对象等等。如果网络等原因引起的登录失败可以归结为异常,如果是用户信息输入错误导致的登录失败算是错误。

假如服务器返回的是统一数据格式:

  1. /**
  2. * 标准数据格式
  3. * @param <T>
  4. */
  5. public class Response<T> {
  6.     public int state;
  7.     public String message;
  8.     public T data;
  9. }
复制代码
  • 网络异常导致的登录失败,在使用Retrofit+RxJava请求时都会直接调用subscribe的onError事件;
  • 密码错误导致的登录失败,在使用Retrofit+RxJava请求时都会调用subscribe的onNext事件;

无论是异常还是错误,都要在subscribe里面处理异常信息,如下代码:

  1. APIWrapper.getInstance().login("username", "password")
  2.                 .subscribe(new Observer<Response<User>>() {
  3.                     @Override
  4.                     public void onCompleted() {

  5.                     }

  6.                     @Override
  7.                     public void onError(Throwable e) {

  8.                     }

  9.                     @Override
  10.                     public void onNext(Response<User> data) {
  11.                         if(data.state == 1001){
  12.                             //.....
  13.                         }else if(data.state == 1002){

  14.                         }
  15.                     }
  16.                 });
复制代码

现在我希望在发生任何错误的情况下,都会调用onError事件,并且由model来处理错误信息。那么,此时我们就应该有一个ExceptionEngine来处理事件流中的错误信息了。

在工作流中处理异常

在正常情况下,我们获取网络数据的流程通常如下:

请求接口->解析数据->更新UI

整个数据请求过程都是发生在Rx中的工作流之中。当有异常产生的时候,我们要尽量不在ui层里面进行判断,换句话说,我们没有必要去告诉ui层具体的错误信息,只需要让他弹出一个信息(Toast或者Dialog)展示我们给它的信息就行。

请求接口和数据解析都可能出错,所以在这两层进行错误处理。为了更好的解耦,我们通过拦截器拦截错误,然后根据错误类型分发信息。

拦截器数据解析层的拦截器

这个拦截器主要是为了获取具体的错误信息,分发给上层的UI,给用户以提示,增强用户体验。

  1. public Observable<Weather> getWeather(String cityName){
  2.         return weatherService.getWeather(cityName)
  3.                 //拦截服务器返回的错误
  4.                 .map(new ServerResponseFunc<Weather>())
  5.                 //HttpResultFunc()为拦截onError事件的拦截器,后面会讲到,这里先忽略
  6.                 .onErrorResumeNext(new HttpResponseFunc<Weather>());
  7.     }
复制代码
  1. //拦截固定格式的公共数据类型Response<T>,判断里面的状态码
  2. private class ServerResponseFunc<T> implements Func1<Response<T>, T> {
  3.         @Override
  4.         public T call(Response<T> reponse) {
  5.             //对返回码进行判断,如果不是0,则证明服务器端返回错误信息了,便根据跟服务器约定好的错误码去解析异常
  6.             if (reponse.state != 0) {
  7.             //如果服务器端有错误信息返回,那么抛出异常,让下面的方法去捕获异常做统一处理
  8.                 throw new ServerException(reponse.state,reponse.message);
  9.             }
  10.             //服务器请求数据成功,返回里面的数据实体
  11.             return reponse.data;
  12.         }
  13.     }
复制代码

所以整个逻辑是这样的:

所以在前三步的过程中,只要发生异常(服务器返回的错误也抛出了)都会抛出,这时候就触发了RxJava的OnError事件。

处理onError事件的拦截器

这个拦截器主要是将异常信息转化为用户”能看懂”的友好提示。

  1. private class HttpResponseFunc<T> implements Func1<Throwable, Observable<T>> {
  2.         @Override
  3.         public Observable<T> call(Throwable throwable) {
  4.             //ExceptionEngine为处理异常的驱动器
  5.             return Observable.error(ExceptionEngine.handleException(throwable));
  6.         }
  7.     }
复制代码
原始地址:
  1. http://blog.csdn.net/jdsjlzx/article/details/51882661
复制代码



捡代码论坛-最全的游戏源码下载技术网站! - 论坛版权郑重声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与捡代码论坛-最全的游戏源码下载技术网站!享有帖子相关版权
3、捡代码论坛版权,详细了解请点击。
4、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,不存在任何商业目的与商业用途。
5、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。 我们不承担任何技术及版权问题,且不对任何资源负法律责任。
6、如无法链接失效或侵犯版权,请给我们来信:jiandaima@foxmail.com

回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立 即 注 册

本版积分规则

技术支持
在线咨询
QQ咨询
3351529868

QQ|手机版|小黑屋|捡代码论坛-专业源码分享下载 ( 陕ICP备15015195号-1|网站地图

GMT+8, 2024-4-27 13:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表