基于retrofit2、rxjava2、OkHttp的网络请求封装,实现背压、网络请求生命周期管理,以及错误码集中处理

1.定义接口地址

/** * Created by PrinceOfAndroid on 2018/4/9 0009. * 接口地址存放类 */

public class ApiUrl {

    //基本地址(要以“/”结尾)
    public static final String BASE_URL = "";

    //请求地址
    public static final String ARTICLE_LIST = "";
}

2.定义接口返回的数据类型

这里根据自己接口返回情况定制(返回数据类型一定要规范)

/** * 
 * author : PrinceOfAndroid * created : 2017/7/5 0005 11:50 * desc : 基本的接口数据返回类型 * 
*/
public class HttpResponse<T> { private int code; //状态码,由后台去定义(如code=200为成功) private String message; private T object; //泛型 最终使用的数据 public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getObject() { return object; } public void setObject(T object) { this.object = object; } }

3.请求接口定义

/** * Created by PrinceOfAndroid on 2018/4/9 0009. */

public interface BaseHttpService {
   /** * get 请求,参数以map的形式传入 * * @param map * @return */
    @GET(ApiUrl.ARTICLE_LIST)
    Flowable> getList(@QueryMap Map map);
}

如果不会的话,可看看retrofit2教程
这里申明返回一个Flowable,至于为啥是Flowable,去看看Rxjava2就知道Flowable有多强大。

4.构建retrofit

/** * Created by PrinceOfAndroid on 2018/4/9 0009. */

public class RetrofitFactory {
    private static BaseHttpService httpService = null;

    public static BaseHttpService getInstance() {
        if (httpService == null) {
            synchronized (RetrofitFactory.class) {
                if (httpService == null) {
                    return createHttpService();
                }
            }
        }
        return httpService;
    }

    private static BaseHttpService createHttpService() {
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new LogInterceptor())  //全局拦截器(这个就自己找个喜欢的拦截器)
                .connectTimeout(8L, TimeUnit.SECONDS)  //连接超时
                .readTimeout(8L, TimeUnit.SECONDS)     //读取超时
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .client(client)                                             //设置okHttp
                .baseUrl(ApiUrl.BASE_URL)                                   //基础地址
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  //引入rxJava2
                .addConverterFactory(GsonConverterFactory.create())         //json 转换
                .build();

        httpService = retrofit.create(BaseHttpService.class);
        return httpService;
    }
}

5.Subscriber的封装

/** * 
 * author: PrinceOfAndroid * date : 2017/7/5 0005 11:30 * desc : 网络请求结果封装(可处理Toast或dialog,但注意内存泄露问题) * 
*/
//这个只是基本功能,还可以通过构造方法传入一些值来做很多事情如:弹窗 public abstract class CommonSubscriber<T> extends ResourceSubscriber<T> { @Override public void onNext(T t) { onSuccess(t); } /** * 通过Throwable处理对应异常 * @param e */ @Override public void onError(Throwable e) { e.printStackTrace(); } /** * 完成 */ @Override public void onComplete() { } /** * 根据具体的Api 业务逻辑去重写 onSuccess 方法!Error 是选择重写,but 必须Super ! * * @param t */ public abstract void onSuccess(T t); }

这里我的CommonSubscriber是继承自ResourceSubscriber,至于为什么,后面会写到。

来个线程切换工具

/** * Created by Administrator on 2018/3/20 0020. * 线程调度 */

public class RxUtils {

    public static  FlowableTransformer applyFSchedulers() {
        return new FlowableTransformer() {
            @Override
            public Publisher apply(Flowable upstream) {
                return upstream.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread());
            }
        };
    }

    /** * 预处理 code处理 * * @param  * @return */
    public static  FlowableTransformer, T> handleResult() {
        return new FlowableTransformer, T>() {
            @Override
            public Publisher apply(Flowable> upstream) {
                return upstream.flatMap(new Function, Flowable>() {
                    @Override
                    public Flowable apply(@NonNull HttpResponse tHttpResponse) throws Exception {
                        if (tHttpResponse.getCode() == 200) {
                            return createData(tHttpResponse.getObject());
                        } else {
                            return Flowable.error(new ApiException("服务器返回error"));
                        }
                    }
                });
            }
        };
    }


    /** * 生成Flowable * * @param  * @return */
    public static  Flowable createData(final T t) {
        return Flowable.create(new FlowableOnSubscribe() {
            @Override
            public void subscribe(FlowableEmitter emitter) throws Exception {
                try {
                    emitter.onNext(t);
                    emitter.onComplete();
                } catch (Exception e) {
                    emitter.onError(e);
                }
            }
        }, BackpressureStrategy.BUFFER);
    }
}

标题中说到的错误码集中处理就在handleResult()这个方法里了
还有 createData(final T t)中使用了BackpressureStrategy.BUFFER,就是标题中的背压

怎么使用呢?

很简单,几句代码就ok了

    Map map = new HashMap<>();
        map.put("is_index", "true");
        map.put("rows", String.valueOf("3"));
        addSubscribe(iModel.getList(map)
                .compose(RxUtils.>applyFSchedulers())
                .compose(RxUtils.handleResult())
                .subscribeWith(new CommonSubscriber() {
                    @Override
                    public void onSuccess(String s) {
                        Log.e("result", s);
                    }
                }));

里面有个iModel,里面代码如下

/** * Created by PrinceOfAndroid on 2018/4/9 0009. * 模型层,负责数据的处理 */

public class LoginModel implements LoginContract.IModel {
    /** * @param map */
    @Override
    public Flowable> getList(Map map) {
        return RetrofitFactory.getInstance()
                .getList(map);
    }
}

看到这里,有人会好奇,为什么是subscribeWith(),而不是subscribe()方法呢
基于retrofit2、rxjava2、OkHttp的网络请求封装,实现背压、网络请求生命周期管理,以及错误码集中处理_第1张图片
看上图就知道,subscribe()是没有返回值的,而subscribeWith()返回了我们传进去的CommonSubscriber。
为什么要这个CommonSubscriber呢?这就要说刚刚写到的ResourceSubscriber了。
这里写图片描述
这里就知道ResourceSubscriber其实是实现Disposable实现方法如下

/** * Cancels the subscription (if any) and disposes the resources associated with * this AsyncObserver (if any). * * 

This method can be called before the upstream calls onSubscribe at which * case the Subscription will be immediately cancelled. */ @Override public final void dispose() { if (SubscriptionHelper.cancel(s)) { resources.dispose(); } }

其实这个就是取消订阅,这个就是我标题写到的生命周期管理了。
有了这些就知道怎么去管理网络请求了,看上面的使用方法中会发现有一个addSubscribe()方法,里面传的就是我们的CommonSubscriber,里面就是对网络请求进行管理的,代码很简单。

 protected void addSubscribe(Disposable subscription) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(subscription);

    }

    protected void unSubscribe() {
        if (mCompositeDisposable != null) {
            mCompositeDisposable.clear();
        }
    }

就是把Disposable 添加到CompositeDisposable中,需要取消订阅的时候如:activity或fragment已经关闭,直接调用
unSubscribe()方法,防止空指针。
这样一来基于retrofit2、rxjava2、OkHttp的网络请求封装就完成了。
如果对于retrofit2 rxjava2不熟悉可以阅读
https://juejin.im/post/5848d96761ff4b0058c9d3dc
https://blog.csdn.net/lmj623565791/article/details/51304204

如果想看源码的话,这里是地址:
https://github.com/PrinceOfAndroid/BaseProject

你可能感兴趣的:(封装)