在android中使用rxjava停止长轮询

时间:2016-11-28 21:48:10

标签: java android rx-java retrofit2

我正在使用retrofit和rxjava从android客户端对API进行long poll。在这种情况下,我们等待来自API的 200 408 超时响应并处理响应或重新连接以再次等待更多数据。这很好用。我需要阻止rx重试某些错误代码(如500)或者如果我想中断该过程,例如我的应用程序是后台,那么让我们停止长轮询。

 retrofitInterface.startPolling()  //returns an Observable 
                    .repeat()
                    .retry()
                    .subscribe(new Subscriber<List<Stuff>>() {
                        @Override
                        public void onCompleted() {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onNext(List<Stuff> updates) {
                             //process stuff
                            }

                        }
                    });

我不确定repeatWhenretryWhen是否是正确的解决方案,我想继续重复并重试对API的http调用但在某些条件下停止重复 (假设我在课堂上将一个bool翻转为假)或者如果状态代码是 500 而不是说 408 则停止重试。

1 个答案:

答案 0 :(得分:1)

如果将请求答案包装在<Response<?>>类型的对象中,则更容易,这使您可以控制错误代码。

我为该用例所做的是在我有一些特定的错误代码时抛出一个特定的异常:

public <T> T throwExceptionIfFailure(T res) {
    Response result = (Response<?>) res;
    if (!result.isSuccessful()) {
        try {
            String msg = result.errorBody().string();
            if (result.code() == 401 || result.code() == 403) {
                invalidateToken();
                msg = context.getString(R.string.invalid_credential);
            } else if (result.code() == 502) {
                msg = context.getString(R.string.server_down);
            }

            throw Exceptions.propagate(new IOException(msg));
        } catch (Throwable e) {
            throw Exceptions.propagate(e);
        }
    } else {
        return res;
    }
}

我在RX的地图函数中添加了这个方法:

    serviceRetrofit.getContacts()
            .map(result -> serviceRetrofit.throwExceptionIfFailure(result))
            .map(result -> createOrUpdateContact(result))
            .retry(4)
            .onErrorReturn(error -> handleErrorEvent(error))
            .doOnCompleted(() -> emitStoreChange(new Store.StoreChangeEvent()))
            .subscribe();