美文网首页
RetroHttp(四) — 实现串联请求

RetroHttp(四) — 实现串联请求

作者: 奔跑的佩恩 | 来源:发表于2021-01-20 14:53 被阅读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类支持发起无序有序串联请求,主要如下:

    • getNextObservable: 支持发起无序串联请求
    • getNextObservableInOrder: 支持发起有序串联请求

    无序串联请求即依次发起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)中提供针对最后一次通讯的模糊提示。

    相关文章

      网友评论

          本文标题:RetroHttp(四) — 实现串联请求

          本文链接:https://www.haomeiwen.com/subject/bpzqzktx.html