使用repeatWhen RxJava2重复Retrofit2请求

时间:2018-04-27 09:27:02

标签: android rx-java retrofit2 rx-java2

我正在使用rxjava2。 我的问题是有时服务器什么也没发送给我(响应体是空的,依此类推大小= 0),所以在这种情况下我想在5秒后重复请求。 我有一个Retrofit2请求:

  @GET("/ics/api/{bidId}/calltracking/reports/widgets")
    Single<List<CallTrackingWidget>> getWidgets(@Path("bidId") int bidId);

像这样使用它:

RetrofitFactory.getRetrofitService().getWidgets(mDataManager.getBidId())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(widgets -> getView().showLoading())
                .doOnSuccess(widgets -> getView().hideLoading())
                .repeatWhen(widgets -> widgets.flatMap(size -> {
                    if ((int) size == 0) {
                        return Flowable.just("asd").delay(5, TimeUnit.SECONDS);
                    } else {
                        return widgets;
                    }
                }))
                .subscribe(widgets -> {
                    mDataManager.getProduct().getCallTrackingData().setWidgets(widgets);
                    getView().initWidgets(mDataManager.getProduct().getCallTrackingData().getWidgetNames());
                }, throwable -> {
                    handleError(throwable, R.string.error_internet);
                })

但我的代码有一个例外:

android.view.ViewRootImpl$CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views.

请帮助我在5秒后重复请求,当列表大小为0时。

2 个答案:

答案 0 :(得分:1)

我认为你的问题在于以下两点:

.doOnSubscribe(widgets -> getView().showLoading())
.doOnSuccess(widgets -> getView().hideLoading())

这两个动作将从主线程执行。如异常所示,您只能从主线程中触摸Android视图。

尝试将此视图操作移动到其他位置。像这样:

getView().showLoading(); // Show loading view
RetrofitFactory.getRetrofitService().getWidgets(mDataManager.getBidId())
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .repeatWhen(widgets - > widgets.flatMap(size - > {
        if ((int) size == 0) {
            return Flowable.just("asd").delay(5, TimeUnit.SECONDS);
        } else {
            return widgets;
        }
    }))
    .subscribe(widgets - > {
        getView().hideLoading(); // Hide loading view
        mDataManager.getProduct().getCallTrackingData().setWidgets(widgets);
        getView().initWidgets(mDataManager.getProduct().getCallTrackingData().getWidgetNames());
    }, throwable - > {
        getView().hideLoading(); // Hide loading view
        handleError(throwable, R.string.error_internet);
    })

答案 1 :(得分:0)

因为您不处理主线程上的视图,所以可以这样写:

RetrofitFactory.getRetrofitService().getWidgets(mDataManager.getBidId())
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnSubscribe(widgets -> getView().showLoading())
    .subscribeOn(AndroidSchedulers.mainThread())
    .repeatWhen(widgets - > widgets.flatMap(size - > {
        if ((int) size == 0) {
            return Flowable.just("asd").delay(5, TimeUnit.SECONDS);
        } else {
            return widgets;
        }
    }))
    .subscribe(widgets - > {
        getView().hideLoading(); // Hide loading view
        mDataManager.getProduct().getCallTrackingData().setWidgets(widgets);
        getView().initWidgets(mDataManager.getProduct().getCallTrackingData().getWidgetNames());
    }, throwable - > {
        getView().hideLoading(); // Hide loading view
        handleError(throwable, R.string.error_internet);
    })