Повторите запрос Retrofit2, используя repeatWhen RxJava2 - PullRequest
0 голосов
/ 27 апреля 2018

Я работаю с 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 голосов
/ 29 июня 2018

Поскольку вы не работаете с представлением в основном потоке, вы можете написать так:

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);
    })
0 голосов
/ 01 мая 2018

Я думаю, что ваша проблема заключается в этих двух строках:

.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);
    })
...