RxJava处理网络连接失败和timer()、interval()、delay

2019-10-14 23:50栏目:终极战队
TAG:

那篇小说算是对【译】对奥迪Q7xJava中.repeatWhen()和.retryWhen()操作符的思量的叁个总结的补偿,提议没看过的先看看下面那篇。

前言

RxJava处理网络连接失败和timer()、interval()、delay()之间的区别。才学EnclavexJava的时候依然挺纳闷的,认为有特意多的对『时间』的操作符,比方timer()interval()delay()defer()RxJava处理网络连接失败和timer()、interval()、delay()之间的区别。等等……
简来讲之功能太强大,直接吓跑了一批初读书人。身边有情人如此跟本身说:

ENVISIONxJava为了省点代码,把逻辑弄这么复杂,望着都晕了,小编宁可多写点 if-else

自己只好回复:用F12berlinettaxJava逻辑断定是变轻巧了,一旦用上手了,再也离不开了。现在让本身写个Thread + HandlerRxJava处理网络连接失败和timer()、interval()、delay()之间的区别。自家都感到费劲。

正题

先看timer()interval()delay()的小球图吧

delay

interval

timer

timer()

此地说的是新本子的timer(),而老版本的timer()已经跟interval()合并了。
timer():创造多少个Observable,它在一个加以的推迟后发射一个非同小可的值
此地须求注意,定义里面说的是『二个』,所以有别于以前用的TimerTasktimer()只是用来成立三个Observable,并延迟发送一回的操作符timer()并不会按周期实行。

interval()

interval():创立三个按一定时间隔离发射整数系列的Observable
以此相比好驾驭,interval()也是用来创设Observable的,并且也得以延缓发送。但interval()是按周期实施的,所以可以这么感到:interval()是贰个方可钦赐线程的TimerTask(威力抓好版……)

delay()

delay():延迟一段钦命的年月再发送来自Observable的出殡结果
语文没学好自然读不懂这一段,作者才看出那句话的时候也懵了……
其实delay()的常规使用跟timer()平等,这分歧在哪呢?delay()是用来流中的操作,跟map()flatMap()的等第是一模一样的。而timer()是用以成立Observable,跟just()from()的品级是同样的。

总结

timer():用于创设Observable,延迟发送二回。
interval():用于成立Observable,跟TimerTask类似,用于周期性发送。
delay():用于事件流中,能够推迟发送事件流中的某一遍发送。

网络连接失利的拍卖

看过最终边那篇文章的应当很明亮retryWhen()是哪些了。
本身再来计算一下,retryWhen()的面前境遇意思正是:产生错误了,接下去该做怎么样。
retryWhen()RxJava的一种错误处理机制,当境遇错误时,将错误传递给另三个Observable来支配是或不是要重复给订阅这一个Observable

延期重试

来虚拟一个风貌:客商用的2G互连网大概WiFi功率信号不稳固,导致互联网常常连接战败,其实今年借使多努力一下就足以接连不断成功了,如若那时弹出荒唐提醒,体验肯定倒霉,所以那边将要选用重试机制

.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
                @Override
                public Observable<?> call(Observable<? extends Throwable> observable) {
                    return observable.flatMap(new Func1<Throwable, Observable<?>>() {
                        @Override
                        public Observable<?> call(Throwable throwable) {
                            return Observable.timer(5, TimeUnit.SECONDS);
                        }
                    });
                }

那边就是三个最简便的一无可取重试机制(别看字母多就复杂,其实逻辑独有两句,用lambda表明式的知道自个儿不是乱说…),借使互连网连接退步那么会每间距5秒举行一回重试,直到连接成功结束。
正要小编说了timer()delay()很像,只是用的机缘不如,所以地方的代码最终的return局地还足以那样写:

return Observable.just(throwable).delay(5, TimeUnit.SECONDS);

判别错误类型

再模拟贰个情状:用户不是手提式有线电话机数字信号不佳,而是根本就没展开网络,此时还傻傻的重试只是萧条电量而已,所以我们得以加二个判定,张开了互连网才重试,没有张开网络就三回九转发送失利的消息。

.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
                @Override
                public Observable<?> call(Observable<? extends Throwable> observable) {
                    return observable.flatMap(new Func1<Throwable, Observable<?>>() {
                        @Override
                        public Observable<?> call(Throwable throwable) {
                            if (throwable instanceof UnknownHostException) {
                                return Observable.error(throwable);
                            }
                            return Observable.timer(5, TimeUnit.SECONDS);
                        }
                    });

步向重试超时

接轨想,重试也不恐怕永久进行,常常都会安装叁个重试超时的体制。这里笔者借用了地点那篇作品的代码:

.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
                @Override
                public Observable<?> call(Observable<? extends Throwable> observable) {
                    return observable.flatMap(new Func1<Throwable, Observable<?>>() {
                        @Override
                        public Observable<?> call(Throwable throwable) {
                            if (throwable instanceof UnknownHostException) {
                                return Observable.error(throwable);
                            }
                            return Observable.just(throwable).zipWith(Observable.range(1, 5), new Func2<Throwable, Integer, Integer>() {
                                @Override
                                public Integer call(Throwable throwable, Integer i) {

                                    return i;
                                }
                            }).flatMap(new Func1<Integer, Observable<? extends Long>>() {
                                @Override
                                public Observable<? extends Long> call(Integer retryCount) {

                                    return Observable.timer((long) Math.pow(5, retryCount), TimeUnit.SECONDS);
                                }
                            });
                        }
                    });
                }

代码变得越多和难读了……试一下lambda表明式看看:

.retryWhen(observable -> observable.flatMap((Throwable throwable) -> {
                if (throwable instanceof UnknownHostException) {
                    return Observable.error(throwable);
                }
                return Observable.just(throwable)
                        .zipWith(Observable.range(1, 5), (throwable1, i) -> i)
                        .flatMap(retryCount -> Observable
                                .timer((long) Math.pow(5, retryCount), TimeUnit.SECONDS));
            }));

那般扬眉吐气多了,然而仍旧先用上边这种吧,终归更多少人还没用到lambda

重试的复用

想转手,未有哪位应用软件独有三个接口地址吧 - -#,即便您用的Retrofit这正是说每三个接口再次来到的Observable都要手动加上上边的重试代码,假如是笔者,笔者一定报告急察方了……所以大家必需把刚刚写的重试代码封装成多少个类:

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

private long mInterval;

    public RetryWhenProcess(long interval) {

        mInterval = interval;
    }

    @Override
    public Observable<?> call(Observable<? extends Throwable> observable) {
        return observable.flatMap(new Func1<Throwable, Observable<?>>() {
            @Override
            public Observable<?> call(Throwable throwable) {
                return observable.flatMap(new Func1<Throwable, Observable<?>>() {
                        @Override
                        public Observable<?> call(Throwable throwable) {
                            if (throwable instanceof UnknownHostException) {
                                return Observable.error(throwable);
                            }
                            return Observable.just(throwable).zipWith(Observable.range(1, 5), new Func2<Throwable, Integer, Integer>() {
                                @Override
                                public Integer call(Throwable throwable, Integer i) {

                                    return i;
                                }
                            }).flatMap(new Func1<Integer, Observable<? extends Long>>() {
                                @Override
                                public Observable<? extends Long> call(Integer retryCount) {

                                    return Observable.timer((long) Math.pow(mInterval, retryCount), TimeUnit.SECONDS);
                                }
                            });
                        }
                    });
            }
        });
    }
}

采取时,只须求丰裕:

.retryWhen(new RetryWhenProcess(5))

即可。

极限互连网拍卖方案

最后,终极的拍卖方案鲜明是那样的:能监听网络连接的播报自动重试,对网络无连接的情状不举行重试,並且重试有逾期机制与重试间隔。
RxJava能够比较便利的达成,请看那篇作品Improving UX with RxJava

版权声明:本文由威尼斯手机娱乐官网平台发布于终极战队,转载请注明出处:RxJava处理网络连接失败和timer()、interval()、delay