RxJava(六) retryWhen操作符实现错误重试机制

标签: RxJavatryWhen操作符
7877人阅读 评论(6) 收藏 举报
分类:

欢迎转载,转载请标明出处:
http://blog.csdn.net/johnny901114/article/details/51539708
本文出自:【余志强的博客】

RxJava系列文章目录导读:

一、RxJava create操作符的用法和源码分析

二、RxJava map操作符用法详解

三、RxJava flatMap操作符用法详解

四、RxJava concatMap操作符用法详解

五、RxJava onErrorResumeNext操作符实现app与服务器间token机制

六、RxJava retryWhen操作符实现错误重试机制

七、RxJava 使用debounce操作符优化app搜索功能

八、RxJava concat操作处理多数据源

九、RxJava zip操作符在Android中的实际使用场景

十、RxJava switchIfEmpty操作符实现Android检查本地缓存逻辑判断

十一、RxJava defer操作符实现代码支持链式调用

十二、combineLatest操作符的高级使用

业务需求

当我们在app里发起网络请求时,可能会因为各种问题导致失败。如何利用RxJava来实现出现错误后重试若干次,并且可以设定重试的时间间隔。

具体实现

网络请求使用Retrofit来做,还是使用上篇博客中的请求用户信息接口

    @GET("/userinfo?noToken=1")
    Observable<Response> getUserInfoNoToken();

下面是请求用户信息接口的逻辑代码

userApi.getUserInfoNoToken()
                        //总共重试3次,重试间隔3000毫秒
                        .retryWhen(new RetryWithDelay(3, 3000))
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Action1<Response>() {
                            @Override
                            public void call(Response response) {
                                String content = new String(((TypedByteArray) response.getBody()).getBytes());
                                printLog(tvLogs, "", content);
                            }
                        }, new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                throwable.printStackTrace();
                            }
                        });

RetryWithDelay

public class RetryWithDelay implements
            Func1<Observable<? extends Throwable>, Observable<?>> {

        private final int maxRetries;
        private final int retryDelayMillis;
        private int retryCount;

        public RetryWithDelay(int maxRetries, int retryDelayMillis) {
            this.maxRetries = maxRetries;
            this.retryDelayMillis = retryDelayMillis;
        }

        @Override
        public Observable<?> call(Observable<? extends Throwable> attempts) {
            return attempts
                    .flatMap(new Func1<Throwable, Observable<?>>() {
                        @Override
                        public Observable<?> call(Throwable throwable) {
                            if (++retryCount <= maxRetries) {
                                // When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).
                                printLog(tvLogs, "", "get error, it will try after " + retryDelayMillis
                                        + " millisecond, retry count " + retryCount);
                                return Observable.timer(retryDelayMillis,
                                        TimeUnit.MILLISECONDS);
                            }
                            // Max retries hit. Just pass the error along.
                            return Observable.error(throwable);
                        }
                    });
        }
    }

如何模拟重试呢?

方法一:把服务器关闭,关闭服务器后,客户端请求接口的必然会报错,看看是不是重试三次。

运行输出:

'get error, it will try after 3000 millisecond, retry count 1'
Main Thread:false, Thread Name:Retrofit-Idle

'get error, it will try after 3000 millisecond, retry count 2'
Main Thread:false, Thread Name:Retrofit-Idle

'get error, it will try after 3000 millisecond, retry count 3'
Main Thread:false, Thread Name:Retrofit-Idle

上面是重试三次了,但是我们怎么知道,如果在服务器启动后,在接下的重试中请求成功呢?接下来试试方法二。

方法二:先把服务器关闭,当点击按钮请求的同时,启动Tomcat服务器。

运行输出:

'get error, it will try after 3000 millisecond, retry count 1'
Main Thread:false, Thread Name:Retrofit-Idle

'get error, it will try after 3000 millisecond, retry count 2'
Main Thread:false, Thread Name:Retrofit-Idle

'username:chiclaim,age:007'
Main Thread:true, Thread Name:main

可以发现,在第三次重试的时候,服务器可用了。


本文的例子放在github上 https://github.com/chiclaim/android-sample/tree/master/rxjava

5
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:830111次
    • 积分:7991
    • 等级:
    • 排名:第2552名
    • 原创:104篇
    • 转载:4篇
    • 译文:1篇
    • 评论:389条
    联系方式
    博客专栏
    最新评论