RetroHttp(四) — 实现串联请求

2021-01-20  本文已影响0人  奔跑的佩恩

前言

RetroHttp作为一个基于Retrofit2.x网络请求的封装库,致力于简洁快速的实现网络通讯,在之前的文章里,我已经对RetroHttp的使用做了些相关介绍,大家感兴趣的话可以参考以下文章:
RetroHttp(一) — 下载使用介绍
RetroHttp(二) — 下载支持增量更新
RetroHttp(三) — kotlin版网络请求

Android网络请求过程中,我们有时会遇到请求串联的情况。即第一个请求发起成功后,才能发起第二个请求。那么今天就让我们来了解下RetroHttp基于串联请求的使用吧。

今天涉及知识有:

  1. 串联请求业务逻辑
  2. 串联请求帮助类ObservableHelper方法简介
  3. 串联请求的使用示例
  4. 需要注意的事项

一. 串联请求业务逻辑

在开发过程中,有时我们回遇到串联请求的情况,如发起注册通讯成功后,立马发起登录的通讯。他们的逻辑特点是,第一个通讯成功后,才发起第二个通讯,当第一个通讯发送失败后,则终止发起后续通讯。这里我将此种通讯逻辑称为串联请求

二.串联请求帮助类ObservableHelper方法简介

RetroHttp库中也支持串联请求,其功能封装到帮助类ObservableHelper中。下面就来看看
ObservableHelper中关于串联请求的方法吧:

    /***
     * 接连发起多个通讯的Observable(一个接一个,但顺序不确定)
     *
     * @param observable
     * @param function  Function<T,R>: T->进入该方法的参数, R->输出结果
     * @param <T>
     * @return
     */
    public static <T>Observable getNextObservable(Observable<T>observable, Function<T, ObservableSource<T>> function)

    /***
     * 按顺序发起通讯的Observable(一个接一个,且按顺序发送)
     *
     * @param observable
     * @param function Function<T,R>: T->进入该方法的参数, R->输出结果
     * @param <T>
     * @return
     */
    public static <T> Observable getNextObservableInOrder(Observable<T>observable, Function<T, ObservableSource<T>> function)

ObservableHelper类支持发起无序有序串联请求,主要如下:

无序串联请求即依次发起ABC三个网络请求,但三个请求返回结果的顺序未知。有序串联请求即依次发起ABC三个网络请求,返回结果的顺序也为ABC

三.串联请求的使用示例

下面以有序串联请求为例,给出其在Presenter中发起网络请求的核心代码:

3.1 Java 版
    public void checkVersion() {
        ApiService apiService = (ApiService) ApiRetrofitor.getInstance().getBaseRetrofitor().getApiService();
        //发起第一个请求
        Observable observable = apiService.checkVersion();
        observable = ObservableHelper.getNextObservableInOrder(observable, new Function<ResponseData, ObservableSource<ResponseData>>() {
            @Override
            public ObservableSource<ResponseData> apply(ResponseData responseData) throws Exception{
                LogUtil.i("=======Function执行apply======");

                //解析第一个通讯的结果
                int code = responseData.getCode();
                //只有在第一此通讯顺利的时候,才发起第二次通讯
                if (code == ResponseCode.SUCCES_CODE) {//成功
                    LogUtil.i("=======准备发起第二次通讯======");
                    //准备发起第二次通讯
                    RequestUser user = new RequestUser();
                    user.setUsername("xxxx");
                    user.setPassword("xxxxxx");
                    return apiService.login(user);
                }
                return null;
            }
        });

//        //按顺序发起第三个通讯
//        observable = ObservableHelper.getNextObservableInOrder(observable, new Function<> ...)

        //加载loading
        LoadingDialog.getInstance().showLoading(mContext);
        //处理最后一次通讯的结果
        RxManager.connect(observable, new ApiObserver<ResponseData>() {
            @Override
            public void doNext(ResponseData responseData) {
                LoadingDialog.getInstance().hideLoading();

                int code = responseData.getCode();
                String message = responseData.getMessage();
                if (code == ResponseCode.SUCCES_CODE) {//成功

                    Object object=responseData.getData();
                    if(object!=null){
                        String temp= GsonUtil.gsonString(object);
                        User user= GsonUtil.gsonToBean(temp,User.class);
                        mView.loginSuccess(user);
                    }else{
                        mView.loginFail("获取信息为空");
                    }
                } else {
                    mView.loginFail(message);
                }
            }

            @Override
            public void doError(ServerException e) {
                LoadingDialog.getInstance().hideLoading();

                LogUtil.i("=====error====="+e.getMessage());
                mView.loginFail("发生错误");

            }
        });
    }
3.2 Kotlin版
    fun checkVersion() {
        var apiService =ApiRetrofitor.getBaseRetrofitor<BaseRetrofitor>().apiService as ApiService
        //发起第一个请求
        var observable: Observable<ResponseData<Any>> = apiService.checkVersion()
        observable = ObservableHelper.getNextObservableInOrder(
            observable,object : Function<ResponseData, ObservableSource<ResponseData>>() {
                @Throws(Exception::class)
                fun apply(responseData: ResponseData): ObservableSource<ResponseData>? {
                    LogUtil.i("=======Function执行apply======")

                    //解析第一个通讯的结果
                    var code = responseData.code
                    //只有在第一此通讯顺利的时候,才发起第二次通讯
                    if (code == ResponseCode.SUCCES_CODE) {//成功
                        LogUtil.i("=======准备发起第二次通讯======")
                        //准备发起第二次通讯
                        var user = RequestUser()
                        user.setUsername("xxxx")
                        user.setPassword("xxxxxx")
                        return apiService.login(user)
                    }
                    return null
                }
            })

//        //按顺序发起第三个通讯
//        observable = ObservableHelper.getNextObservableInOrder(observable, new Function<> ...)

        //加载loading
        LoadingDialog.getInstance().showLoading(mContext)
        //处理最后一次通讯的结果
        RxManager.connect(observable, object : ApiObserver<ResponseData>() {
            fun doNext(responseData: ResponseData) {
                LoadingDialog.getInstance().hideLoading()

                var code = responseData.code
                var message = responseData.message
                if (code == ResponseCode.SUCCES_CODE) {//成功

                    var obj = responseData.data
                    if (obj != null) {
                        var temp = GsonUtil.gsonString(obj)
                        var user = GsonUtil.gsonToBean(temp, User::class.java)
                        mView.loginSuccess(user)
                    } else {
                        mView.loginFail("获取信息为空")
                    }
                } else {
                    mView.loginFail(message)
                }
            }

            fun doError(e: ServerException) {
                LoadingDialog.getInstance().hideLoading()

                LogUtil.i("=====error=====" + e.message)
                mView.loginFail("发生错误")
            }
        })
    }

四.需要注意的事项

这里需要注意的是,以上面依次发起的两个请求为例,checkVersion()发起的请求在第一个getNextObservableInOrder中接收并处理,然后在该方法的apply(T t)方法中一般只处理第一个同通讯获取成功的情况,处理OK后接着在此方法中发起第二个请求。若第一个通讯失败,则失败的处理会有结尾的RxManager.connect(...)来处理。若还想发起第三个请求,则像上面代码一样,在后面接着写observable = ObservableHelper.getNextObservableInOrder(observable, new Function<> ...),然后在此方法中处理第二个请求的接收值,处理完后,发起第三个请求...
最后用RxManager.connect(...)来处理最后一个请求的返回值。值得注意的是,在RxManager.connect(...)doError(ServerException e)中将处理所有请求的异常处理。由于串联请求的特点,会导致doError(ServerException e)无法判断处理的是哪一个通讯的异常,故在开发过程中,我们只会在doError(ServerException e)中提供针对最后一次通讯的模糊提示。

上一篇下一篇

猜你喜欢

热点阅读