Retrofit和RxJava网络请求二次封装

目前Retrofit和RxJava结合使用已经是非常普遍了,也是现在最热门的一种网络请求方式,今天我们来聊聊,如何对Retrofit + RxJava 网络请求框架实现二次封装,以供大家在项目中可以应用到,也供大家学习和参考

首先我们先来看看关于Retrofit和RxJava最基本的使用

  1. 我们需要去定义一个对应接口的Service和返回的实体类
public class Content<T> {
    private List<T> list;

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }
}
实体类省略....
public interface OrderApi {

    @GET("order/findByCustomerIdOrderList")
    Observable<List<Order>> findByCustomerIdOrderList(@Query("offset") int offset, @Query("max") int max);
}

2.初始化Retrofit

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.wanhulian.com")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

3.使用方式

 OrderApi orderApi= retrofit.create(OrderApi.class);
 Observable<List<Order>> observable = orderApi.findByCustomerIdOrderList(0,5)
 observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<GankResultBean>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(GankResultBean gankResultBean) {

                    }
                });

实现起来还是比较简单的,但是如果每次都要写这么一大串代码,是不是觉得很麻烦,而且很不利于后期项目维护。这个时候我就该考虑一下对代码进行封装了。

4.首先我们创建一个RetrofitUtil类,私有化构造函数,里面创建了一个OkHttpClient对象,进行相关信息的配置,然后用单例模式来获取实例

public class RetrofitUtil {
    private static RetrofitUtil instance;
    private Retrofit retrofit;
    private static Gson gson;

    private RetrofitUtil(){
        OkHttpClient client = new OkHttpClient();
        client.setConnectTimeout(5000, TimeUnit.MILLISECONDS);
        retrofit = new Retrofit.Builder().baseUrl(NetUrl.BASE_URL)
                                         .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                                         .addConverterFactory(GsonConverterFactory.create(getGson()))
                                         .client(client)
                                         .build();
    }

    public static RetrofitUtil getInstance(){
        if(instance == null){
            synchronized (RetrofitUtil.class){
                if(instance == null){
                    instance = new RetrofitUtil();
                }
            }
        }
        return instance;
    }

    public static Gson getGson() {
        if (gson == null) {
            gson = new GsonBuilder()
                    .registerTypeAdapter(Date.class, new TypeAdapter<Date>() {
                        @Override
                        public void write(JsonWriter out, Date value) throws IOException {
                            out.value(value == null ? null : value.getTime());
                        }

                        @Override
                        public Date read(JsonReader in) throws IOException {
                            if (in.peek() == JsonToken.NULL) {
                                in.nextNull();
                                return null;
                            }
                            return new Date(in.nextLong());
                        }
                    })
                    .create();
        }
        return gson;
    }
    public OrderApi getOrderApi(){
        return retrofit.create(OrderApi.class);
    }
    //获取血压数据
    public void findByCustomerIdOrderList(Subscriber<Content<Order>> subscriber, int offset, int max){
        Observable<Content<Order>> observable = getOrderApi().findByCustomerIdOrderList( offset, max).map(new HttpResultFunc<Content<Order>>());
        toSubscribe(observable,subscriber);

    }

    private <T> void toSubscribe(Observable<T> o, Subscriber<T> s){
        o.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s);
    }
    /**
     * 用来统一处理HttpresultCode,并将HttpResultData部分剥离出来返回给subscriber
     *
     * @param <T>   Subscriber真正需要的数据类型,也就是Data部分的数据类型
     */
    private class HttpResultFunc<T> implements Func1<KmResult<T>,T> {

        @Override
        public T call(KmResult<T> kmResult) {
            if (kmResult.getErrorCode() == -1) {
                throw new ApiException(100);
            }
            return kmResult.getContent();
        }
    }
}

这里对KmResult做一个说明,因为后台返回的数据格式一般都是这样的:

 {
   code:1,
   msg:"your message",
   data:[]
}

所以我们创建了一个KmResult类,结合HttpResultFunc类,将数据结构里面的 data分离出来

public class KmResult<T> {
    private int code;
    private String msg;

    private T data;

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.ode = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "KmResult{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

5.接着我们创建了一个ApiException类,主要是对后台返回的code进行处理

 public class ApiException extends RuntimeException {

    public static final int ERROR_INTERNET = 100;

    public ApiException(int resultCode) {
        this(getApiExceptionMessage(resultCode));
    }

    public ApiException(String detailMessage) {
        super(detailMessage);
    }

    /**
     * 由于服务器传递过来的错误信息直接给用户看的话,用户未必能够理解
     * 需要根据错误码对错误信息进行一个转换,在显示给用户
     * @param code
     * @return
     */
    private static String getApiExceptionMessage(int code){
        String message = "";
        switch (code) {
            case ERROR_INTERNET:
                message = "网络不可连接";
                break;
            default:
                message = "未知错误";

        }
        return message;
    }
}

6.然后我们再新建一个MySubscriber类继承Subscriber类,实现onCompleted,onError,onNext三个方法,这样的话我们只需要对onNext方法进行处理。

public class MySubscriber<T> extends Subscriber<T> {
    private SubscriberOnNextListener<T> mSubscriberOnNextListener;
    private Context mContext;
    public MySubscriber(SubscriberOnNextListener<T> subscriberOnNextListener,Context context){
        mSubscriberOnNextListener = subscriberOnNextListener;
        mContext = context;
    }
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {
        if (e instanceof SocketTimeoutException) {
            Toast.makeText(mContext, "网络中断1,请检查您的网络状态", Toast.LENGTH_SHORT).show();
        } else if (e instanceof ConnectException) {
            Toast.makeText(mContext, "网络中断2,请检查您的网络状态", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(mContext, "error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
    }
}

    @Override
    public void onNext(T t) {
        if (mSubscriberOnNextListener != null) {
            mSubscriberOnNextListener.onNext(t);
        }
    }
}

通过接口回调的方式,让调用者自己去实现onNext里面的代码。

public interface SubscriberOnNextListener<T> {
    void onNext(T t);
}

7.最后,我们只要通过一两行代码就可以实现网络请求了。

 RetrofitUtil.getInstance().findByCustomerIdOrderList(new MySubscriber<>(new SubscriberOnNextListener<Content<Order>>() {
            @Override
            public void onNext(Content<Order> orderContent) {
               List<Order> orderList = orderContent.getList();
            }
        }, getActivity()),0,5);
    }

这个就是我在项目中对Retrofit + RxJava网络请求框架的二次封装,希望对大家对Retrofit + RxJava的学习有所帮助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值