处理Retrofit + RxJava2 + Room的网络错误

时间:2017-09-05 16:02:04

标签: android retrofit2 rx-java2 android-room

我在努力解决如何将数据层中的网络错误引发到视图层时遇到了困难。

我使用Room以及RxJava2和Retrofit2。我将存储库模式实现为local-first,因此我在从远程获取时查询本地数据,并在必要时更新本地数据。在代码中,这将是:

public Flowable<List<DEvent>> getAll() {
    return db.dEventDataStore().getAll()
        .doOnSubscribe(new Consumer<Subscription>() {
            @Override
            public void accept(final Subscription subscription) throws Exception {
                dEventApi.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new MaybeObserver<List<DEvent>>() {
                        @Override
                        public void onSubscribe(@NonNull Disposable disposable) {
                            Timber.d("Remote onSubscribe");
                        }

                        @Override
                        public void onSuccess(@NonNull List<DEvent> dEvents) {
                            Timber.d("Remote onSuccess!");
                            db.dEventDataStore().insertAll(dEvents);
                        }

                        @Override
                        public void onError(@NonNull Throwable throwable) {
                            Timber.d("Remote onError!");
                        }

                        @Override
                        public void onComplete() {
                            Timber.d("Remote onComplete!");
                        }
                    }
                );
            }
        });
}

在视图层中:

    mDisposable.add(repo.getAll()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<List<DEvent>>() {
                @Override
                public void accept(List<DEvent> dEvents) throws Exception {
                    Timber.d("OnNext!!");
                    mView.showEvents(dEvents);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    Timber.e("Error on getting DEvents - " + Log.getStackTraceString(throwable));
                }
            }));

我怎样才能发出那个扔掉的?

1 个答案:

答案 0 :(得分:1)

您并未在此处链接这些Observable - 因此API Observable中的错误不会沿着流传播到视图层。 (此外,我不确定Room如何运行,但您会在数据库更新时查询两次)

如果我理解正确,db.dEventDataStore().getAll()由Room创建,这样Flowable是无限的,听取DB更改并发出任何更改。所以你想查询服务器,并且在数据更新数据库的情况下,并期望从Room的DB Flowable发出。

在这种情况下,您可以使用merge并行执行此操作,而API可能会通过忽略它发出的任何元素来传递错误。通过这种方式下游,我们只能从Room DB获取数据,同时仍然收到服务器错误通知。

 public Flowable<List<DEvent>> getAll() {
    return Flowable.merge(
            db.dEventDataStore().getAll(),
            dEventApi.getAll()
                    .doAfterSuccess(dEvents -> db.dEventDataStore().insertAll(dEvents))
                    .ignoreElement()
                    .toFlowable()
    );
}