RxJava和Retrofit2的统一处理单个请求示例详解

前言

RxJava和Retrofit2用了一段时间了,写个小例子,分享出来,有什么不对的地方还请大神在评论区指正。

什么是Retrofit2

官网是这么介绍的:

Retrofit adapts a Java interface to HTTP calls by using annotations on the declared methods to
define how requests are made。

我翻译的可能不准确,他的大概意思是说:Retrofit 是一个 java 接口类,以注解的方式用于 HTTP 网络请求。那下面我们一起来看看是怎么使用的?

发现问题

最近在帮兄弟公司做一个资讯类的项目,使用了RxJava和Retrofit2这对黄金组合,在编写代码的过程中发现有很多很多的网络请求都需要做.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).onErrorReturn()的处理,为避免这样,需要沉思。

解决问题

import android.util.Log;

import com.wei.caiqiwang.data.entity.BaseResponse;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class RxNet {
 /**
  * 统一处理单个请求
  */
 public static <T> Subscription request(Observable<BaseResponse<T>> observable, final RxNetCallBack<T> callBack) {
  return observable
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .onErrorReturn(new Func1<Throwable, BaseResponse<T>>() {
     @Override
     public BaseResponse<T> call(Throwable throwable) {
      Log.v("LinNetError",throwable.getMessage());
      callBack.onFailure(ExceptionHandle.handleException(throwable));
      return null;
     }
    })
    .subscribe(new Subscriber<BaseResponse<T>>() {
     @Override
     public void onCompleted() {

     }

     @Override
     public void onError(Throwable e) {

     }

     @Override
     public void onNext(BaseResponse<T> baseResponse) {
      if (baseResponse.getCode().equals("200")) {
       callBack.onSuccess(baseResponse.getData());
      } else {
       callBack.onFailure(baseResponse.getMsg());
      }
     }
    });

 }

 /**
  * 统一处理单个请求没有 msg body
  */
 public static Subscription requestWithoutBody(Observable<BaseResponse> observable, final RxNetCallBack<String> callBack) {
  return observable
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .onErrorReturn(new Func1<Throwable, BaseResponse>() {
     @Override
     public BaseResponse call(Throwable throwable) {
      callBack.onFailure(ExceptionHandle.handleException(throwable));
      return null;
     }
    })
    .subscribe(new Subscriber<BaseResponse>() {
     @Override
     public void onCompleted() {

     }

     @Override
     public void onError(Throwable e) {

     }

     @Override
     public void onNext(BaseResponse baseResponse) {
      if (baseResponse.getCode().equals("200")) {
       callBack.onSuccess(baseResponse.getMsg());
      } else {
       callBack.onFailure(baseResponse.getMsg());
      }
     }
    });

 }
}

回调就是普通的回调

public interface RxNetCallBack<T> {
 /**
  * 数据请求成功
  *
  * @param data 请求到的数据
  */
 void onSuccess(T data);

 /**
  * 数据请求失败
  */
 void onFailure(String msg);
}

错误异常处理(可能不全):

import android.net.ParseException;

import com.google.gson.JsonParseException;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;

import java.net.ConnectException;

import retrofit2.HttpException;

public class ExceptionHandle {

 private static final int UNAUTHORIZED = 401;
 private static final int FORBIDDEN = 403;
 private static final int NOT_FOUND = 404;
 private static final int REQUEST_TIMEOUT = 408;
 private static final int INTERNAL_SERVER_ERROR = 500;
 private static final int BAD_GATEWAY = 502;
 private static final int SERVICE_UNAVAILABLE = 503;
 private static final int GATEWAY_TIMEOUT = 504;

 public static String handleException(Throwable e) {
  String errorMsg;
  if (e instanceof HttpException) {
   HttpException httpException = (HttpException) e;
   switch (httpException.code()) {
    case UNAUTHORIZED:
    case FORBIDDEN:
    case NOT_FOUND:
    case REQUEST_TIMEOUT:
    case GATEWAY_TIMEOUT:
    case INTERNAL_SERVER_ERROR:
    case BAD_GATEWAY:
    case SERVICE_UNAVAILABLE:
    default:
     errorMsg = "网络错误";
     break;
   }
   return errorMsg + ":" + httpException.code();
  } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) {
   return "解析错误";
  } else if (e instanceof ConnectException) {
   return "连接失败";
  } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
   return "证书验证失败";
  } else if (e instanceof ConnectTimeoutException) {
   return "连接超时";
  } else if (e instanceof java.net.SocketTimeoutException) {
   return "连接超时";
  } else {
   return "未知错误";
  }
 }
}

然后就是ApiManager:

import android.util.Log;

import com.wei.demo.data.AppConstants;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiManager {

 private Retrofit client;

 private ApiManager() {
  client = new Retrofit.Builder()
    .baseUrl(AppConstants.Base_Url_Api_Test)
    .client(initClient())
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .addConverterFactory(GsonConverterFactory.create())
    .build();
 }

 private static volatile DemoApi INSTANCE;

 public static DemoApi getInstance() {
  if (INSTANCE == null) {
   synchronized (ApiManager.class) {
    if (INSTANCE == null) {
     INSTANCE = new ApiManager().getApi();
    }
   }
  }
  return INSTANCE;
 }

 private DemoApi getApi() {
  return client.create(DemoApi.class);
 }

 private static OkHttpClient initClient() {
  OkHttpClient.Builder builder = new OkHttpClient.Builder();
  //声明日志类
  HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
   @Override
   public void log(String message) {
    Log.v("NetLog", message);
   }
  });
  //设定日志级别
  httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
  //延时
  builder.addInterceptor(httpLoggingInterceptor)
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(10, TimeUnit.SECONDS)
    .writeTimeout(10, TimeUnit.SECONDS);
  return builder.build();
 }
}

怎么用?

 RxNet.request(ApiManager.getInstance().getUserMsg(map), new RxNetCallBack<List<MsgBean>>() {
   @Override
   public void onSuccess(List<MsgBean> data) {
    // 处理数据
   }

   @Override
   public void onFailure(String msg) {
    //出现了错误
    showToast(msg);

   }
  });

Demo https://github.com/FriendLin/NetRequestDemo (本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • RxJava2.x+ReTrofit2.x多线程下载文件的示例代码

    写在前面: 接到公司需求:要做一个apk升级的功能,原理其实很简单,百度也一大堆例子,可大部分都是用框架,要么就是HttpURLConnection,实在是不想这么干.正好看了两天的RxJava2.x+ReTrofit2.x,据说这俩框架是目前最火的异步请求框架了.固本文使用RxJava2.x+ReTrofit2.x实现多线程下载文件的功能. 如果对RxJava2.x+ReTrofit2.x不太了解的请先去看相关的文档. 大神至此请无视. 思路分析: 思路及其简洁明了,主要分为以下四步 1.获取

  • Retrofit+Rxjava实现文件上传和下载功能

    Retrofit简介: 在Android API4.4之后,Google官方使用了square公司推出的okHttp替换了HttpClient的请求方式.后来square公司又推出了基于okHttp的网络请求框架:Retrofit. 什么是 RxJava? RxJava 是一个响应式编程框架,采用观察者设计模式.所以自然少不了 Observable 和 Subscriber 这两个东东了. RxJava 是一个开源项目,地址:https://github.com/ReactiveX/RxJava

  • Retrofit+Rxjava下载文件进度的实现

    前言 最近在学习Retrofit,虽然Retrofit没有提供文件下载进度的回调,但是Retrofit底层依赖的是OkHttp,实际上所需要的实现OkHttp对下载进度的监听,在OkHttp的官方Demo中,有一个Progress.java的文件,顾名思义.点我查看. 准备工作 本文采用Dagger2,Retrofit,RxJava. compile'com.squareup.retrofit2:retrofit:2.0.2' compile'com.squareup.retrofit2:con

  • Retrofit Rxjava实现图片下载、保存并展示实例

    首先我们看一下Retrofit常规的用法,在不使用Rxjava的情况下,我们默认返回的是Call. public interface ServiceApi { //下载文件 @GET Call<ResponseBody> downloadPicFromNet(@Url String fileUrl); } 但是如果我们要配合Rxjava使用,那么就要按照如下方式来重新定义我们的方法: @GET Observable<ResponseBody> downloadPicFromNet(

  • Android中的Retrofit+OkHttp+RxJava缓存架构使用

    RxJava如何与Retrofit结合 先扔出build.gradle文件的内容 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.2.0' compile 'io.reactivex:rxjava:1.1.0' compile 'io.reactivex:rxand

  • RxJava+Retrofit+OkHttp实现多文件下载之断点续传

    背景 断点续传下载一直是移动开发中必不可少的一项重要的技术,同样的Rxjava和Retrofit的结合让这个技术解决起来更加的灵活,我们完全可以封装一个适合自的下载框架,简单而且安全! 效果 实现 下载和之前的http请求可以相互独立,所以我们单独给download建立一个工程moudel处理 1.创建service接口 和以前一样,先写接口 注意:Streaming是判断是否写入内存的标示,如果小文件可以考虑不写,一般情况必须写:下载地址需要通过@url动态指定(不适固定的),@head标签是

  • rxjava+retrofit实现多图上传实例代码

    在看了网上多篇rxjava和retrofit的文章后,大概有了一个初步的认识,刚好要做一个多图上传的功能,就拿它开刀吧.下面的内容将基于之前实现方式和使用rxjava实现之间的异同展开,初次写笔记不喜就喷. 普通版多图上传 由于目前手机照片动辄几M的大小,如果不做处理就直接上传,我就笑笑不说话(给个眼神你自己体会).所以,上传分为两步:对图片进行压缩和请求上传.下面请看伪代码(PS:自己不会写后台,项目后台不能拿来用,所以只能给伪代码了) //图片集合 List<String> imgs =

  • RxJava+Retrofit+OkHttp实现文件上传

    背景 在实际运用中上传是一个必不可少的功能,所以我们在封装二的基础上加入上传的功能,同时需要附带上传进度! 效果 实现 1.定义service接口 注意:Multipart是指定大文件上传过程中的标示,一般上传图片的过程中我们需要附带信息,所以我们需要用到@part指定传递的数值,MultipartBody.Part是指定传递的文件: /*上传文件*/ @Multipart @POST("AppYuFaKu/uploadHeadImg") Observable<BaseResul

  • 详解RxJava2 Retrofit2 网络框架简洁轻便封装

    前言 RxJava2.Retrofit2火了有一段时间了,前段时间给公司的项目引入了这方面相关的技术,在此记录一下相关封装的思路. 需求 封装之前要先明白需要满足哪些需求. RxJava2衔接Retrofit2 Retrofit2网络框架异常的统一处理 兼容fastjson(可选) RxJava2内存泄漏的处理 异步请求加入Loading Dialog 依赖 implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation

  • Kotlin结合Rxjava+Retrofit实现极简网络请求的方法

    前言 因为最近正在写的项目集成了两个网络请求框架(Volley and Retrofit)对比之下也是选择了Retrofit.既然选择那自然要让自己以后开发更加省力(就是懒).于是我在Retrofit中加入了Rxjava,这也是当下蛮流行的一个请求框架.然后又利用了Kotlin的一些新特性,使网络请求变得特别简单,代码量特别少. Kotlin镇楼 RxJava RxJava学习是一个曲折漫长的过程,但一旦掌握,妙用无穷. 通过这里了解更多:http://www.jb51.net/article/

随机推荐