博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RxJava练武场之——Observable网络框架的解耦和复用
阅读量:5797 次
发布时间:2019-06-18

本文共 4423 字,大约阅读时间需要 14 分钟。

RxJava练武场是一个rxjava在项目中应用的小系列,包括:

Observable网络框架的解耦和复用

Observer一端的解耦

我们可以看到BaseObserver实际做了errorcode响应,loading控制,对外接口的定义等工作。这几部分工作集中在一个类中有一定的耦合。我们设计的目标是业务使用自定义的Observer或者直接使用BaseObserver都很方便,但目前的设计业务要么使用BaseObserver全部功能,要么自己从头定义,扩展性不强。 我们可以如下优化:

将callback接口化

BaseObserver定义的onSuccess(T)和onFail(boolean isException ,Object object)两个抽象方法是完全面向业务使用者的。可将其抽象为接口:

public interface ObserverCallback 
>{ /** * 请求成功 * @param t */ void onSuccess(T t); /** * 请求失败 * @param isException true:返回Throwable false:返回String(ErrorMsg) * @param object */ void onFail(boolean isException ,Object object);}复制代码

化为接口有两个作用

  1. 规范自定义的Observer的回调接口。
  2. 可以与其他的网络请求调用方式(callback方式,非observable方式),回调接口上统一,降低切换成本。
将loading逻辑和error响应逻辑分离

定义LoadingObserver,其实现ObserverCallback接口

public abstract class LoadingObserver
> implements Observer
,ObserverCallback
{ protected BaseContext mBaseContext; public LoadingObserver(BaseContext baseContext){ mBaseContext = baseContext; } @Override public void onSubscribe(Disposable d) { if (isShowProgress()) { showProgress(true); } } @Override public void onNext(T t) { if (isShowProgress()) { showProgress(false); } onSuccess(t); } @Override public void onError(Throwable e) { if (isShowProgress()) { showProgress(false); } } @Override public void onComplete() { if (isShowProgress()) { showProgress(false); } } protected void showProgress(boolean isShow){ if (mBaseContext != null) { mBaseContext.showLoading(isShow); } } /** * 网络请求是否loading显示 * @return */ protected boolean isShowProgress(){ return true; }}复制代码

这样做: 1、将更为通用的loading逻辑抽离,使其可以被独立使用或继承。 2、如果app存在不同业务线,可将error影响单独处理(不同业务线code定义可能不同),将loadingObserver类下沉,适配多业务线情况

BaseObserver代码如下:
public abstract class  MapiObserver
> extends LoadingObserver
{ public MapiObserver(BaseContext baseContext){ super(baseContext); } @Override public void onError(Throwable e) { super.onError(e); handleError(e); } private void handleError(Throwable e){ //handle error code }}复制代码

至此,Observer被分为了三层,原来BaseObserver这一层可以由多个更为具体的Observer来扩展。每一层都有自己的扩展功能。

ObservableSource一端的解耦

我们看下Observable一端做了哪些事情:

  1. 对Request 参数做发送前处理:组合和加密处理
  2. 返回Response 解密处理,Java实体化
  3. 返回Response code码判断及分类

Observable端解耦的目的

  1. 耦合性降低后,方便后续的扩展和组合
  2. 将公共的,不易变化的逻辑下沉

这是最终Observable生成的代码:

private static Observable
sendRequest(final HttpRequest request,final TypeReference
t) { return NetHelper.getApiObservable(request) .map(new JavaBeanFunc(t)) .compose(ResponseTransformer.handleResult()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread());}复制代码
Request请求params参数组合加密处理放到何处?

前面一章已经提到,params是通过HttpRequest类中的getURLParam()方法完成。 原因有2点 1、params定义在HttpRequest中,在Httprequest类中拿最方便。 2、组合和加密的过程如果需要定制,那么直接在HttpRequest子类中就可以,和框架不会有耦合。

Response解密处理,Java实体化,在何处处理?

Response解密处理网上有两种处理方式, 1、在okhttp里使用interceptor拦截器解密 2、ResponseTransformer中处理。 这两种方式都有问题: 虽然app内部一般解密方式不变,但是要适应多业务线,或者作为适应性更广的框架来讲,这块解密逻辑放到框架中显然耦合性太高。 我们采用的方式是定义接口:

public interface ResponseDecryptHandler {    String decrypt(String var1) throws IOException;}复制代码

HttpRequest类中定义实现接口,并将这种解密方式作为Convertor设置给Retrofit,这样将加密的逻辑耦合转移到了HttpRequest基类中

addConverterFactory(SecurityConvertFactory.create(request.responseDecryptHandler()))复制代码

对于JavaBean实体化,一般都采用fastJson方式,这里我们通过map操作符完成,作为链式调用中的一环出现,替换方便。

.map(new JavaBeanFunc(t))复制代码
Response的code解析,在何处处理?

前面提到,response的code分为了解析和处理两个部分,分别放在observable和observer中完成。其中ResponseTransformer是用于解析response的返回值。 ErrorResumeFunction和ResponseFunction分别是网络错误和业务错误,网络错误不会变,业务错误的判断是可能扩展的。ResponseFunction的实现是可以多样的。


private static Observable
sendRequest(final HttpRequest request,final TypeReference
t) { return NetHelper.getApiObservable(request) .map(new JavaBeanFunc(t)) .compose(ResponseTransformer.handleResult()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread());}复制代码

以上可以看出Observable的生成过程中,除了一部分的逻辑放入的Request的接口中用于扩展,其他的功能在Observable的生成过程中以链式调用的方式存在,每个链式调用的功能由一个类承担。这也是rxjava的优势所在,在调用方式上天然地将各部分解耦了。

转载地址:http://snsfx.baihongyu.com/

你可能感兴趣的文章
Oracle ASM 翻译系列第六弹:高级知识 如何映射asmlib管理的盘到它对应的设备名...
查看>>
多线程之volatile关键字
查看>>
如何判断webview是不是滑到底部
查看>>
Raptor实践2——控制结构
查看>>
Smartisan OS一步之自定义拖拽内容
查看>>
海贼王十大悲催人物
查看>>
org.hibernate.MappingException: No Dialect mapping for JDBC type: -1 搞定!
查看>>
热点热词新闻资讯API开放接口(永久免费开放)
查看>>
【第二章】 IoC 之 2.2 IoC 容器基本原理 —— 跟我学Spring3
查看>>
8.1_Linux习题和作业
查看>>
11.排序算法_6_归并排序
查看>>
Redis redis-cli 命令列表
查看>>
.NET框架设计—常被忽视的框架设计技巧
查看>>
ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结
查看>>
BigDecimal 舍入模式(Rounding mode)介绍
查看>>
开源 免费 java CMS - FreeCMS1.2-标签 infoSign
查看>>
开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据
查看>>
git reset 三种用法总结
查看>>
Android多任务断点续传下载
查看>>
hdfs笔记
查看>>