Rxjava+retrofit 添加公共请求参数及请求结果封装

来源:互联网 发布:重庆时时彩报号软件 编辑:程序博客网 时间:2024/05/21 08:55

RxJava + Retrofit + okHttp 做为当前android主流的网络请求框架,今天我就写一些自己在项目中的应用!本文主要内容:1.为所用请求添加公共的请求参数。2.封装适合于自己app的接口请求回调。

开发环境

retrofitVersion = ‘2.2.0’
ok3Version = ‘3.6.0’
rxjavaVersion = ‘1.2.7’
rxAndroidVersion = ‘1.2.1’
rxlifecycleVersion = ‘0.3.0’
主要说一下,rxlifecycleVersion是为了防止RxJava中subscription导致内存泄漏而诞生的。例如:当要引用的view(fragment,activity)被销毁,但rxjava生命周期未结束时,再次调用已销毁的view(fragment,activity)会产生异常!
使用方法也比较简单,网上有很多例子可以参考,本文重点不再此处!


  • 形如一个Post接口:http://base/interface/xxx
    每个接口都有一个必传字段:APPTOKEN
    返回值可能为:
{"erron":"100000","msg":"成功"}//接口返回单纯消息{"data":{},"erron":"100000","msg":"成功"}//接口返回带有详细字段{"nowPage":"1","totalPage":"4","data":[],"erron":"100000","msg":"成功"}//接口返回分页数据

首先处理apptoken这里用到一个Okhttp3的网络拦截器Interceptor,详细使用方法请自行百度谷歌。
核心代码:

builder = new OkHttpClient.Builder();        if (BuildConfig.DEBUG) {            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();            logging.setLevel(HttpLoggingInterceptor.Level.BODY);            builder.addInterceptor(logging);        }        builder.connectTimeout(6 * 1000, TimeUnit.MILLISECONDS)//10s连接超时                .readTimeout(10 * 1000, TimeUnit.MILLISECONDS)                .writeTimeout(10 * 1000, TimeUnit.MILLISECONDS);        //添加token拦截器        builder.addInterceptor(new TokenInterceptord());        Interceptor netErrorInterceptor = new Interceptor() {            @Override            public Response intercept(Chain chain) throws IOException {                if (NetWorkUtil.isNetworkConnected())                    return chain.proceed(chain.request());                else {                    String res = "{\"erron\":\"-1200\",\"msg\":\"网络连接失败\",\"nowPage\":\"0\",\"totalPage\":\"0\"}";                    Response response = new Response.Builder()                            .code(200)                            .request(chain.request())                            .protocol(Protocol.HTTP_1_1)                            .addHeader("Cache-Control", "no-cache")                            .addHeader("Content-Type", "text/html; charset=utf-8")                            .body(RealResponseBody.create(MediaType.parse("text"), res.getBytes("utf-8")))                            .build();                    return response;                }            }        };        builder.addNetworkInterceptor(netErrorInterceptor);

可以看到我上文中添加了两个网络拦截器,其中添加apptoken的拦截器是应用拦截器(Application Intercetor),添加网络异常的拦截器是网络拦截器(netErrorInterceptor)。retrofit使用的okhttp就是这个。
apptoken拦截器的详细实现:

public class TokenInterceptord implements Interceptor {    @Override    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        Request.Builder requestBuilder = request.newBuilder();        if (canInjectIntoBody(request)) {            FormBody.Builder formBodyBuilder = new FormBody.Builder();            formBodyBuilder.add("apptoken", SharedPreUtil.getAppToken());//此处添加apptoken参数            RequestBody formBody = formBodyBuilder.build();            String postBodyString = bodyToString(request.body());            postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);            requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));        }        request=requestBuilder.build();        return chain.proceed(request);    }    private boolean canInjectIntoBody(Request request) {        if (request == null) {            return false;        }        if (!TextUtils.equals(request.method(), "POST")) {            return false;        }        RequestBody body = request.body();        if (body == null) {            return false;        }        MediaType mediaType = body.contentType();        if (mediaType == null) {            return false;        }        if (!TextUtils.equals(mediaType.subtype(), "x-www-form-urlencoded")) {            return false;        }        return true;    }    private String bodyToString(final RequestBody request) {        try {            final RequestBody copy = request;            final Buffer buffer = new Buffer();            if (copy != null)                copy.writeTo(buffer);            else                return "";            return buffer.readUtf8();        } catch (final IOException e) {            return "did not work";        }    }}

其实就是拦截我们的request请求并添加了一个apptoken。
* 接下来分析3种返回类型,一般app接口应该差不多就这3种情况。
1. 针对第一种:

{“erron”:”100000”,”msg”:”成功”}//接口返回单纯消息信息

我的处理结果BaseBeanSubscribe

public abstract class BaseBeanSubscribe<T extends BaseBean> extends Subscriber<T> {    public enum ERROR_TYPE {        DATA_EMPTY,//数据为空        DATA_ERROR,//数据解析错误        NET_ERROR,//网络连接错误        TOKEEN_ERROR,//apptoken无效或异常。    }    @Override    public void onCompleted() {    }    @Override    public void onError(Throwable e) {        LogUtils.i("Zuzu", "ResultSubscriber-->exception");        e.printStackTrace();        if (NetWorkUtil.isNetworkConnected()) {            onError(ERROR_TYPE.DATA_ERROR, "未知异常!");        } else {            onError(ERROR_TYPE.NET_ERROR, "网络连接超时,请检测您的网络状况!");        }        LogUtils.i("Zuzu", "request fail!");    }    @Override    public void onNext(T t) {        if (t == null) {            LogUtils.i("Zuzu", "data_empty!");            onError(ERROR_TYPE.DATA_EMPTY, "服务器异常!");        } else if ("100002".equals(t.getErron()) || "100003".equals(t.getErron())) {            String msg;            if ("-1".equals(SharedPreUtil.getAppToken())) {                msg = "您还没有登录,不能进行该操作!";            } else {                msg = "抱歉您账户已过期,请重新登录!";            }            onError(ERROR_TYPE.TOKEEN_ERROR, msg);        } else if ("100000".equals(t.getErron())) {            sucess();        } else if ("-1200".equals(t.getErron())) {            onError(ERROR_TYPE.NET_ERROR, t.getMsg());        } else {            onError(ERROR_TYPE.DATA_ERROR, t.getMsg());        }    }    //请求成功    protected abstract void sucess();    //发生错误!    protected abstract void onError(ERROR_TYPE type, String msg);}其中basebeanpublic class BaseBean<T> {    private String erron;    private String msg;    private T data;    ...set get方法...}

该代码段实现了根据结果过滤集处理错误的情况。

2 . 第二种:

{“data”:{},”erron”:”100000”,”msg”:”成功”}//接口返回带有详细字段

public abstract class ResultSubscriber<D, T extends BaseBean<D>> extends BaseBeanSubscribe<T> {    @Override    public void onNext(T t) {        if (t != null && "100000".equals(t.getErron())) {            onSuccess(t.getData());            return;        }        super.onNext(t);    }    @Override    protected void sucess() {    }    //请求成功    protected abstract void onSuccess(D data);}

这样写的好处是onSuccess中返回的数据是”data”:{}的数据。
3. 最后一种类型,分页:

{“nowPage”:”1”,”totalPage”:”4”,”data”:[],”erron”:”100000”,”msg”:”成功”}

public abstract class PageListResultSubscriber<D, T extends BasePageBean<D>> extends ResultSubscriber<List<D>, T> {    @Override    public void onNext(T t) {        if (t != null && "100000".equals(t.getErron())) {            onSuccess(t.getData(), Integer.parseInt(t.getNowPage()), Integer.parseInt(t.getTotalPage()));            return;        }        super.onNext(t);    }    protected abstract void onSuccess(List<D> data, int nowPage, int totalPage);    @Override    protected void onSuccess(List<D> data) {        //空实现    }

onSucess中返回List集合,以及totalpage,及nowpage
* 最后完成上述准备工作,代码中的使用就简单多了
eg:一个接口

@POST(“admin/index/surnames”)
@FormUrlEncoded
Observable getBjxList(@Field(“id”) String id);

mService.getBjxList("0")                .compose(getView().<BjxListBean>bindToLifecycle())                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new ResultSubscriber<List<BjxListBean.DataBean>,BjxListBean>() {                    @Override                    protected void onSuccess(List<BjxListBean.DataBean> data) {                        if(getView()!=null)                        {                            getView().showSucessUi(data);                        }                    }                    @Override                    protected void onError(ERROR_TYPE type, String msg) {                        if(getView()!=null)                        {                            getView().showError(type,msg);                        }                    }                });其中BjxListBeanpublic class BjxListBean extends BaseBean<List<BjxListBean.DataBean>> {    public static class DataBean implements Serializable{        private String id;        private String xing;        public String getId() {            return id;        }        public void setId(String id) {            this.id = id;        }        public String getXing() {            return xing;        }        public void setXing(String xing) {            this.xing = xing;        }    }}
阅读全文
0 0
原创粉丝点击