我正在使用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时。
答案 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);
})