java封装拦截请求,GitHub - TBoyLi/Rxjava2RetrofitTMvp: Rxjava2 Retrofit 简单封装 自定义拦截器,中断请求等...

Rxjava2RetrofitTMvp

Rxjava2 Retrofit 简单封装 自定义拦截器,中断请求等

OK 、 老规矩直接上图,看着图来说话

68747470733a2f2f75706c6f61642d696d616765732e6a69616e7368752e696f2f75706c6f61645f696d616765732f313738303538302d646264656362333234323064393361612e6769663f696d6167654d6f6772322f6175746f2d6f7269656e742f7374726970abe271a8279954d505394cee5164f79c.gif

至于为什么要优化呢。主要是因为如下:

第一、mvp上一篇文章呢代码呢在项目中rxjava的生命周期写着麻烦,现加入了rxlifecycle2来简化,主要参考RxActivity.java 文件 让BaseActivity继承它即可,使用起来方便

private final BehaviorSubject lifecycleSubject = BehaviorSubject.create();

/**

* 基本的网络请求都是向服务器请求数据,客户端拿到数据后更新UI。但也不排除意外情况,比如请求回数据途中Activity已经不在了,这个时候就应该取消网络请求。

* 要实现上面的功能其实很简单,两部分

*

* 随时监听Activity(Fragment)的生命周期并对外发射出去; 在我们的网络请求中,接收生命周期

* 并进行判断,如果该生命周期是自己绑定的,如Destory,那么就断开数据向下传递的过程

* 实现以上功能需要用到Rxjava的lifecycleSubject

*

*/

第二、Rxjava中在ProgressSubscriber.java 文件 构造方法中加 isShowLoading方法来控制是否显示loading dialog,在实际项目中可能会第一次进入界面加载数据显示dialog 刷新和加载更多呢不用显示dialog。而此参数满足了其需求

public ProgressSubscriber(SubscriberOnNextListener mSubscriberOnNextListener, Context context, boolean isShowLoading) {

this.mSubscriberOnNextListener = mSubscriberOnNextListener;

this.context = context;

this.isShowLoading = isShowLoading;

this.mProgressDialogHandler = new ProgressDialogHandler(context, this, true);

}

第三、Retrofit 加入了拦截器(包括头,请求体,返回数据)和cookie机制,拦截器方便调试中查阅网络请求的问题,至于cookie机制就不用多说了,无非就是解决用户重复登录而已。具体参考HeaderInterceptor 头部拦截器 LoggerInterceptor 请求拦截器

请看

D/ProgressSubscriber: onSubscribe:

V/LoggerInterceptor: POST

https://api.douban.com/v2/movie/top250

count=10

start=1

消耗时间:2036.0609ms

{

"count": 20,

"start": 0,

"total": 250,

"subjects": [

{

"rating": {

"max": 10,

"average": 9.6,

"stars": "50",

"min": 0

},

"genres": [

"\u72af\u7f6a",

"\u5267\u60c5"

],

"title": "\u8096\u7533\u514b\u7684\u6551\u8d4e",

"casts": [

{

"alt": "https:\/\/movie.douban.com\/celebrity\/1054521\/",

"avatars": {

"small": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p17525.jpg",

"large": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p17525.jpg",

"medium": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p17525.jpg"

},

"name": "\u8482\u59c6\u00b7\u7f57\u5bbe\u65af",

"id": "1054521"

},

{

"alt": "https:\/\/movie.douban.com\/celebrity\/1054534\/",

"avatars": {

"small": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p34642.jpg",

"large": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p34642.jpg",

"medium": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p34642.jpg"

},

"name": "\u6469\u6839\u00b7\u5f17\u91cc\u66fc",

"id": "1054534"

},

{

"alt": "https:\/\/movie.douban.com\/celebrity\/1041179\/",

"avatars": {

"small": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p5837.jpg",

"large": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p5837.jpg",

"medium": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p5837.jpg"

},

"name": "\u9c8d\u52c3\u00b7\u5188\u987f",

"id": "1041179"

}

],

"collect_count": 1247012,

"original_title": "The Shawshank Redemption",

"subtype": "movie",

"directors": [

{

"alt": "https:\/\/movie.douban.com\/celebrity\/1047973\/",

"avatars": {

"small": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p230.jpg",

"large": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p230.jpg",

"medium": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p230.jpg"

},

"name": "\u5f17\u5170\u514b\u00b7\u5fb7\u62c9\u90a6\u7279",

"id": "1047973"

}

],

"year": "1994",

"images": {

"small": "https://img3.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p480747492.jpg",

"large": "https://img3.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p480747492.jpg",

"medium": "https://img3.doubanio.com\/view\/photo\/s_ratio_poster\/public\/p480747492.jpg"

},

"alt": "https:\/\/movie.douban.com\/subject\/1292052\/",

"id": "1292052"

},

{

"rating": {

"max": 10,

"average": 9.5,

"stars": "50",

"min": 0

},

"genres": [

"\u5267\u60c5",

"\u7231\u60c5",

"\u540c\u6027"

],

"title": "\u9738\u738b\u522b\u59ec",

"casts": [

{

"alt": "https:\/\/movie.douban.com\/celebrity\/1003494\/",

"avatars": {

"small": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p67.jpg",

"large": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p67.jpg",

"medium": "https://img1.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p67.jpg"

},

"name": "\u5f20\u56fd\u8363",

"id": "1003494"

},

{

"alt": "https:\/\/movie.douban.com\/celebrity\/1050265\/",

"avatars": {

"small": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p46345.jpg",

"large": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p46345.jpg",

"medium": "https://img3.doubanio.com\/view\/celebrity\/s_ratio_celebrity\/public\/p46345.jpg"

},

"name": "\u5f20\u4e30\u6bc5",

"id": "1050265"

},

{

"alt": "https:\/\/movie.douban

D/ProgressSubscriber: onNext:

D/ProgressSubscriber: onComplete:

是不是很方便,这是请求成功,至于错误信息也来张截图,但是这不是ProgressSubscriber 截断出来的。待会介绍

第三、错误信息更加智能化,自定义错误信息更方便主要参考ProgressSubscriber文件 ApiException 文件

自定义 ApiException

public enum ApiException {

/**

* 解析数据失败

**/

PARSE_ERROR,

/**

* 网络问题

**/

BAD_NETWORK,

/**

* 连接错误

**/

CONNECT_ERROR,

/**

* 连接超时

**/

CONNECT_TIMEOUT,

/**

* section token past due 过期

**/

TOKEN_PAST_DUE,

/**

* 未知错误

**/

UNKNOWN_ERROR,

}

发起异常信息

@Override

public void onError(Throwable e) {

Log.e("onError", e.getMessage());

dismissProgressDialog();

if (e instanceof SocketException) {

onException(context, CONNECT_ERROR);

} else if (e instanceof HttpException) {

// HTTP错误

onException(context, BAD_NETWORK);

} else if (e instanceof ConnectException

|| e instanceof UnknownHostException) {

// 连接错误

onException(context, CONNECT_ERROR);

} else if (e instanceof InterruptedIOException) {

// 连接超时

onException(context, CONNECT_TIMEOUT);

} else if (e instanceof JsonParseException

|| e instanceof JSONException

|| e instanceof ParseException) {

// 解析错误

onException(context, PARSE_ERROR);

} else {

onException(context, UNKNOWN_ERROR);

}

}

/**

* 回调异常

*

* @param reason

*/

private void onException(Context context, ApiException reason) {

switch (reason) {

case CONNECT_ERROR:

mSubscriberOnNextListener.onFail(context.getString(R.string.connect_error));

break;

case CONNECT_TIMEOUT:

mSubscriberOnNextListener.onFail(context.getString(R.string.connect_timeout));

break;

case BAD_NETWORK:

mSubscriberOnNextListener.onFail(context.getString(R.string.bad_network));

break;

case PARSE_ERROR:

mSubscriberOnNextListener.onFail(context.getString(R.string.parse_error));

break;

case UNKNOWN_ERROR:

default:

mSubscriberOnNextListener.onFail(context.getString(R.string.unknown_error));

break;

}

}

错误信息:(断网错误)

03-22 20:53:47.442 19620-19620/com.redli.rxjava2retrofittmvp D/ProgressSubscriber: onSubscribe:

03-22 20:53:47.505 19620-19620/com.redli.rxjava2retrofittmvp E/onError: Network is unreachable

可根据自己需求而定义 ( 主code返回信息来判断 )

第四、中断请求处理,其实我看上面的打印日志就只知道 observer 的执行顺序了,在没有错误的情况下 onSubscribe → onNext → onComplete ,有错的情况下 onSubscribe → onError ,中断请求是怎么做到的呢。我们具体看 onSubscribe 方法的参数 Disposable 类,其实说白了Disposable 就是一个管道而已,链接上游observable 和 下游 observer的,中断就是让这个管道破裂。让下游的消息接受打到上游的消息,但是,上游是发着消息的哦。看ProgressSubscriber文件代码说明

@Override

public void onSubscribe(Disposable s) {

Log.d(TAG, "onSubscribe: ");

//获取管道

this.disposable = s;

if (isShowLoading) {

showProgressDialog();

}

}

@Override

public void onCancelProgress() {

Log.d(TAG, "onCancelProgress: ");

//截断信息,下游接受不到信息

if (!this.disposable.isDisposed()) {

this.disposable.dispose();

}

}

第五、model多接口的回调,不用每次都请求都在new一个model

第六的话就是Rxjava 和 Retrofi 的版本升级和去除第一篇文章 本地存储机制,使 Rxjava + Retrofi + Mvp 更加简洁和更好的拓展

最后呢祝大家新年新气象,财运滚滚,欢迎start 和 issue

小编来赚个辛苦钱,Thanks

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值