2 votes

RxJava fait en sorte que retryWhen() déclenche la méthode onError()

J'ai une classe suivante avec une implémentation RxJava pour télécharger deux ressources depuis une API. Je fais quelques rx pour lui permettre de réessayer ou de répéter quand il ne répond pas aux exigences de l'api/connexion. Cependant, je ne peux pas faire en sorte que retryWhen() déclenche onError() après plus de 3 tentatives.

QUESTION / AIDE

veuillez, examiner mon code et m'aider à résoudre ce problème.

NOTE

J'implémente Rx en lisant ces deux articles. article 1, article 2

SplashPresenter.class

public class SplashPresenter implements SplashContract.Presenter {

    private static final String TAG = SplashPresenter.class.getName();
    private static final int RETRY_TIMEOUT = 10;
    private static final int STOP_RETRY_TIME = 3;
    private static final int START_RETRY_TIME = 1;

    private SplashContract.View mView;

    @Override
    public void init(SplashContract.View view) {
        this.mView = view;
    }

    @Override
    public void onResume() {

        GetRemoteReceiverRelationshipSpec relationSpec = new GetRemoteReceiverRelationshipSpec();
        GetRemoteIncompleteReasonSpec reasonSpec = new GetRemoteIncompleteReasonSpec();

        Observable>> queryReason = Repository.getInstance().query(reasonSpec);

        Repository.getInstance().query(relationSpec)
                .concatMap(result -> queryReason)
                .repeatWhen(complete -> complete
                        .zipWith(Observable.range(START_RETRY_TIME, STOP_RETRY_TIME), (v, i) -> i)
                        .flatMap(repeatCount -> {
                            Log.i(TAG, "Tentative de répétition : " + repeatCount);
                            mView.showLoadingDialog();
                            return Observable.timer(RETRY_TIMEOUT, TimeUnit.SECONDS);
                        }))
                .takeUntil(RepoResult::isSuccess)
                .retryWhen(error -> error
                        .zipWith(Observable.range(START_RETRY_TIME, STOP_RETRY_TIME), (v, i) -> i)
                        .flatMap(retryCount -> {
                            Log.i(TAG, "Tentative de réessai : " + retryCount);
                            mView.showLoadingDialog();
                            if (mView.getCommunicator() != null) {
                                mView.getCommunicator().onConnectionFail(retryCount);
                            }
                            return Observable.timer(RETRY_TIMEOUT, TimeUnit.SECONDS);
                        }))
                .filter(RepoResult::isSuccess)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        result -> Log.i(TAG, "onNext()"),
                        err -> {
                            Log.i(TAG, "onError()");
                            if (mView.getCommunicator() != null) {
                                mView.dismissLoadingDialog();
                                mView.getCommunicator().onSplashScreeDismissError();
                            }
                        },
                        () -> {
                            Log.i(TAG, "onComplete()");
                            if (mView.getCommunicator() != null) {
                                mView.dismissLoadingDialog();
                                mView.getCommunicator().onSplashScreenSuccessDismiss();
                            }
                        }
                );
    }

    @Override
    public void onPause() {

    }
}

1voto

Matthew Mayaki Points 11

Pour conserver l'exception après une nouvelle tentative (au lieu d'émettre une personnalisée), retournez un Observable avec l'erreur appropriée de l'opérateur zipWith lorsque le retryCount dépasse la limite spécifiée.

.retryWhen(erreur -> {
                Observable range = Observable.range(START_RETRY_TIME, STOP_RETRY_TIME);
                Observable> zipWith = erreur.zipWith(range, (e, i) ->
                        i < STOP_RETRY_TIME ?
                                Observable.timer(i, TimeUnit.SECONDS) :
                                Observable.error(e));
                return Observable.merge(zipWith);
            });

0voto

ytRino Points 1046

Lorsque j'ai écrit un code similaire auparavant, j'avais manuellement lancé Observable.error() dans flatMap

.flatMap(retryCount -> {
    if (retryCount >= STOP_RETRY_TIME) {
        return Observable.error(someException);
    }
    return Observable.timer(RETRY_TIMEOUT, TimeUnit.SECONDS);
 }))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X