Rxjava2 + Retrofit + Mvp

这篇文章主要是针对前一篇文章Android TMvp+RxJava+Retrofit 封装的优化和升级

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


总览.gif

Rxjava2 + Retrofit + Mvp_第1张图片
中断请求.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 请求拦截器
请看logger

03-22 20:50:48.070 19620-19620/com.redli.rxjava2retrofittmvp D/ProgressSubscriber: onSubscribe: 
03-22 20:50:50.157 19620-10787/com.redli.rxjava2retrofittmvp 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
03-22 20:50:50.206 19620-19620/com.redli.rxjava2retrofittmvp D/ProgressSubscriber: onNext: 
03-22 20:50:50.206 19620-19620/com.redli.rxjava2retrofittmvp 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


Rxjava2 + Retrofit + Mvp_第2张图片
微信收钱.jpeg
Rxjava2 + Retrofit + Mvp_第3张图片
支付宝收钱.jpeg

你可能感兴趣的:(Rxjava2 + Retrofit + Mvp)