昂CoraxJava2 实战体系作品

XC60xJava2 实战知识梳理(1) – 后台执行耗费时间操作,实时通报 UI
更新

宝马7系xJava2 实战知识梳理(2) –
计算一段时间内数据的平均值

CR-VxJava2 实战知识梳理(3) –
优化搜索联想效能

猎豹CS6xJava2 实战知识梳理(4) – 结合 Retrofit
请求音讯资源音信

RAV4xJava2 实战知识梳理(5) –
简单及进阶的轮询操作

SportagexJava2 实战知识梳理(6) –
基于错误类型的重试请求

昂科威xJava2 实战知识梳理(7) – 基于 combineLatest
达成的输入表单验证

中华VxJava2 实战知识梳理(8) – 使用 publish + merge
优化先加载缓存,再读取网络数据的伸手进程

HighlanderxJava2 实战知识梳理(9) – 使用 timer/interval/delay
完结任务调度

福特ExplorerxJava2 实战知识梳理(10) – 显示器旋转导致 Activity
重建时上涨任务

KoleosxJava2 实战知识梳理(11) –
检查和测试互联网状态并自行重试请求

昂科雷xJava2 实战知识梳理(12) – 实战讲解 publish & replay & share & refCount
& autoConnect

陆风X8xJava2 实战知识梳理(13) –
怎么样使得错误产生时不自行终止订阅关系

TiggoxJava2 实战知识梳理(14) – 在 token 过期时,刷新过期 token
等量齐观复发起呼吁

OdysseyxJava2 实战知识梳理(15) – 达成三个简单的 MVP + 中华VxJava + Retrofit
应用


壹 、产生错误时停下订阅的图景

RxJava中,如若产生了不当,那么 订阅者会自动截至对上游的订阅关系
,大家将招致订阅撤销的错误分成三种:

  • 上游:上游发生错误,并发送onError事件给订阅者。
  • 下游:订阅者在onNext中拍卖时发出了卓殊。

RxJava的设计中,假如产生了不当,那么订阅关系就收回了。可是在好曾几何时候,我们愿意在错误发生的时候不要撤废订阅,因为那样订阅者只有重新通过subscribe措施展才能能接到音信,类似的情景如监测数据源变化、RxBus的贯彻等。

大家先用多个简单的事例来演示一下上边提到的三种景况:

1.1 上游传递音讯时发生错误

订阅者在始发时候订阅到mPublishObject,当该PublishObject发送到第陆个事件时,主动抛出四个那多少个,以模拟上游发生尤其的情况。

     private void upError() {
        mPublishSubject.map(new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer integer) throws Exception {
                if (integer == 4) {
                    throw new RuntimeException();
                }
                return integer;
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(getNormalObserver());
    }

    private Observer<Integer> getNormalObserver() {
        return new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }
            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "onNext=" + value);
            }
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError=" + e);
            }
            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete");
            }
        };
    }

从控制台的出口能够见到,当第陆回发送事件后,由于上游发生了那多少个,因此订阅者收到了onError事件,之后它就再也无能为力吸收消息了。

1.2 订阅者处理新闻时发出错误

下边,大家再来看订阅读处理理音信时产生错误的景色:

    private void downError() {
        mPublishSubject.observeOn(AndroidSchedulers.mainThread()).subscribe(getErrorObserver());
    }

    private LambdaObserver<Integer> getErrorObserver() {
        return new LambdaObserver<>(new Consumer<Integer>() {
            @Override
            public void accept(Integer value) throws Exception {
                Log.d(TAG, "onNext=" + value);
                if (value == 4) {
                    throw new RuntimeException();
                }
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Log.d(TAG, "onError=" + throwable);
            }
        }, new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "onComplete");
            }
        }, new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {

            }
        });
    }

我们在订阅者收到第多个数据的时候抛出二个这些,此时间控制制台的输出为如下,与地点类似,之后订阅者都无法吸收到消息,因为订阅关系一度被免去了。

贰 、发生极度时的拍卖办法

2.1 上游产生错误

在上游产生错误的时候,一般通过重订阅的不二法门来化解。大家得以依据错误的连串判断是还是不是必要重订阅,重订阅的时候利用retryWhen操作符,那一个大家在
福特ExplorerxJava2 实战知识梳理(6) –
基于错误类型的重试请求

已经介绍过了。

下边,大家演示一下在上边的一无可取当中如何回复:

    private void upErrorIgnore() {
        mPublishSubject.map(new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer integer) throws Exception {
                if (integer == 4) {
                    throw new RuntimeException("retry");
                } else if (integer == 8) {
                    throw new RuntimeException("don't retry");
                }
                return integer;
            }
        }).observeOn(AndroidSchedulers.mainThread()).retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
                //第一步,通过flatMap对错误进行响应。
                return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(Throwable throwable) throws Exception {
                        //第二步:根据错误的类型判断是否需要重订阅。
                        return "retry".equals(throwable.getMessage()) ? Observable.just(0) : Observable.empty();
                    }
                });
            }
        }).subscribe(getNormalObserver());
    }

在第七次/第7次点击的是不是,大家独家在上游抛出三个老大,那样就会接触retryWhen的回调,在中间大家分为注释中的两部分开始展览处理,第四回的时候发起重订阅,而第四回则不提倡,因而,第七个事件订阅者就收不到了,控制台的输出为:

2.2 订阅者发生错误

但是retryWhen唯其如此处理上游发生错误的事态,对于地点说的第贰种意况并无法处理,由此假使是上边介绍的第二种状态:订阅者在onNext拍卖中发生错误的动静,照旧会免去订阅关系。

此处首先要感谢 Johnny
Shieh

提供的化解办法,在 RxJava 2 版本的
Rxbus

一文中,他分析了这一题材的原因,那是因为在LambdaObserver的源码中,借使在onNext中产生了分外,那么首先会调用onError方法,而onError中会执行撤废订阅的操作。

消除办法正是,把 LambdaObserver
代码拷贝出来,注释掉这句,然后继续于它去贯彻 Observer
,代码在
RxSample
的十三章例子中。

从控制台能够见到,并没有消除订阅关系,在发生错误之后,如故能够持续吸收接纳多少。


愈多小说,欢迎访问作者的 Android 知识梳理连串:

网站地图xml地图