Rxjava2.x 封装总结
来源:互联网 发布:飞升虫子升级数据 编辑:程序博客网 时间:2024/05/16 10:51
封装作为java的三大特性之一,相信每个开发者对封装技术点都能说出一些,但是真正到项目实际开发,很多开发者都没有注意,今天这篇博客主要总结一下rxjava2.0使用过程中一些封装。
一、线程调度封装
先上一段简单的代码,比较常见。
Flowable.timer(3000, TimeUnit.MILLISECONDS) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) throws Exception { } });
上面这段代码只是简单做了一下延迟,很常见的写法,这个应该怎么样优化呢?大家有没有注意线程调度这里,每个接口几乎有线程调度相关的操作,这里可不可以封装一下呢??答案是可以的
/** * 统一线程处理 * @param <T> * @return */ public static <T> FlowableTransformer<T, T> rxSchedulerHelper() { //compose简化线程 return new FlowableTransformer<T, T>() { @Override public Flowable<T> apply(Flowable<T> observable) { return observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }; }
通过使用使用compose()操作符,compose()里接收一个FlowableTransformer对象,FlowableTransformer是个接口,通过实现这个接口,将FlowableTransformer转化成 Publisher,接下来上面倒计时那段代码就可以写成这个样子
Flowable.timer(3000, TimeUnit.MILLISECONDS)// .subscribeOn(Schedulers.io())// .observeOn(AndroidSchedulers.mainThread()) .compose(RxUtil.<Long>rxSchedulerHelper()) .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) throws Exception { } });
二、UI、异常相关封装
我们平时网络请求的的代码中,大概的套路都是这样,发请网络请求后,在页面上弹个正在加载的页面,请求成功或者失败后取消正在加载的页面,展示相应的页面。比较笨的方法,每次请求在onStart()中展示进度,onNext()onComplete或取消,展示页面,其实也没毛病,就是代码重复率太高,效率低,接下来我们把这个操作简单的封装一下。
public abstract class CommonSubscriber<T> extends ResourceSubscriber<T> { private BaseView mView; private String mErrorMsg; private boolean isShowErrorState = true; protected CommonSubscriber(BaseView view){ this.mView = view; } @Override public void onError(Throwable e) { if (mView == null) { return; } if (mErrorMsg != null && !TextUtils.isEmpty(mErrorMsg)) { mView.showErrorMsg(mErrorMsg); } else if (e instanceof ApiException) { mView.showErrorMsg(e.toString()); } else if (e instanceof HttpException) { mView.showErrorMsg("数据加载失败"); } else { mView.showErrorMsg("未知错误"); } if (isShowErrorState) { mView.stateError(); } } @Override protected void onStart() { super.onStart(); mView.stateLoading(); } @Override public void onComplete() { mView.stateMain(); }}
这里我简单的解释一下,BaseView用于处理View相关的状态的接口,具体写法看自己的业务需求,不多解释。重点看一下ResourceSubscriber这个类,查看源码我们发现此类实现了FlowableSubscriber, Disposable,主要功能是 允许异步取消其订阅相关资源,节省内存而且是线程安全。这样我们就可以在subscribeWith(这个方法可以返回当前订阅的观察者)中使用自定义这个类了。
Flowable.timer(3000, TimeUnit.MILLISECONDS) .compose(RxUtil.<Long>rxSchedulerHelper()) .subscribeWith(new CommonSubscriber<Long>(this) { @Override public void onNext(Long aLong) { Log.e(TAG, "accept: 三秒后执行"); } });
我在CommonSubscriber类中,onStart和onComplete方法中分别打了一个log,输出如下;
有图有真相,跟我们预想中的一样,所以我在开发中只需关注onNext()中数据相关的就可以了。
三、服务器返回数据统一封装
我们在平时开发中,后台返回的数据格式都应该一致的(除非你们公司后台是刚毕业的实习生),比较常见的接口返回类型如下,目前我们公司后台数据格式就是这个,当然别的类型也没毛病,大同小异。
private int code; private String message; private T data;
通过code判断是否是成功与否,错误信息封装在message中,data就是我们最终关心的数据,正常情况我们一般这么做,我简单写个伪代码:
if(data.getCode() == 200) { return code; } else { return message; }
以上这段代码几乎每个网络请求都要这么写,甚至还要判断data不为空,蜜汁缩进,我们View中最关心的是展示给用户的数据(data)及当发生错误时候展示给用户的提示(message),view(mvp模式中 presenter)并不需要知道怎么来的,接下来我就针对这个情况封装一下。
/** * 统一返回结果处理 * @param <T> * @return */ public static <T> FlowableTransformer<MyHttpResponse<T>, T> handleMyResult() { //compose判断结果 return new FlowableTransformer<MyHttpResponse<T>, T>() { @Override public Flowable<T> apply(Flowable<MyHttpResponse<T>> httpResponseFlowable) { return httpResponseFlowable.flatMap(new Function<MyHttpResponse<T>, Flowable<T>>() { @Override public Flowable<T> apply(MyHttpResponse<T> tMyHttpResponse) { if(tMyHttpResponse.getCode() == 200) { return createData(tMyHttpResponse.getData()); } else { return Flowable.error(new ApiException(tMyHttpResponse.getMessage(), tMyHttpResponse.getCode())); } } }); } }; }
createData()
/** * 生成Flowable * @param <T> * @return */ public static <T> Flowable<T> createData(final T t) { return Flowable.create(new FlowableOnSubscribe<T>() { @Override public void subscribe(FlowableEmitter<T> emitter) throws Exception { try { emitter.onNext(t); emitter.onComplete(); } catch (Exception e) { emitter.onError(e); } } }, BackpressureStrategy.BUFFER); }
接下来,在我们代码中就可以这样搞了,上面的例子不适用这个了,我截取了一段我们项目中判断当前版本号的代码,如下
apiService.appversion(test1, test2) .compose(RxUtil<MyHttpResponse <VersionBean>>rxSchedulerHelper()) .compose(RxUtil.<VersionBean>handleMyResult()) .//省略
以上就是我对Rxjava的简单封装,并且已经在项目中实际使用过,使用起来比较舒服,省去很多啰嗦的代码。各位读者发现有什么错误或者有更好的建议,请在下面评论指出,谢谢!
- Rxjava2.x 封装总结
- rxjava2.x
- retrofit2+rxjava2封装解析
- 简单封装retrofit2+rxjava2
- 一步步封装Retrofit + RxJava2
- Rxjava2+okhttp3+Retrofit2封装
- RxJava2 + Retrofit2 优雅简洁封装
- RxJava2+retrofit实现网络封装
- Retrofit2+Rxjava2联网的封装
- Retroit+rxjava2.0+mvp封装
- (备忘录)Rxjava2+Retrofit封装1
- (备忘录)Rxjava2+Retrofit封装2
- RxJava2.0学习总结
- Rxjava2.x学习记录(三)
- RxJava1.X升级到RxJava2.X笔记
- RxJava1.X升级到RxJava2.X笔记
- RxJava2.x+ReTrofit2.x多线程下载文件
- Rxjava2.0和Retrofit简单封装使用
- 使用input + label替代placeholder
- BT渗透
- 记录
- java 设计模式六大原则
- Ruby学习笔记(18)_冒号用法
- Rxjava2.x 封装总结
- 用vmware装的黑苹果终于可以上网了
- java中关于String、StringBuffer和StringBuilder
- 一个子查询涉及的索引位置问题
- JS实现吸附(adsorption)效果
- Java拦截过滤器模式
- Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNest
- flask web开发-用户认证部分代码分析(二)
- 如何取数组的下标索引