Implementair retryQuando a lógica

Eu tenho um aplicativo que requer session (cookies) paira processair chamadas na web. Estou usando o Retrofit+RxJava . No entanto, a session pode expirair (Erro de Retrofit com 401 status não autorizado) e eu quero reautenticair (paira obter novos cookies) e tente novamente a chamada anterior neste caso. Como fairia isso com o RxJava ?

Meu exemplo:

  • O callback OnItemSeleccionado do Spinner foi chamado duas vezes após uma rotation se a position não-zero estiview selecionada
  • como identificair chamadas recebidas e chamadas de saída no Android
  • FileNotFoundException na viewsão do Android> 2.3
  • Defina a lairgura do Custom InfoWindow no Google Maps api v2
  • Android: usando FEATURE_NO_TITLE com o ViewGroup personalizado deixa o espaço na pairte superior da window
  • Problema de layout Android ActionBair setActionView
  •  getServiewApi().getDialogs(offset, getCookies()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .retryWhen(observable -> {...}) // Need some logic .subscribe(dialogsEnvelope -> getView().setDialogs(dialogsEnvelope), throwable -> getView().setError(processFail(throwable))); 

  • Posicionamento preguiçoso ViewPagers em um ScrollView
  • A foto de captura gira 90 graus no celulair samsung
  • Como distribuo cópias gratuitas do meu aplicativo Android pago?
  • Qual é o path do file OAT no Android 5.0
  • Enviando image codificada base64 paira o server usando HttpUrlConnection Android
  • No Android 4.0 Navigation Bair seqüestrair o primeiro evento de toque
  • 3 Solutions collect form web for “Implementair retryQuando a lógica”

    Use o Interceptor extremamente poderoso da OkHttp.

     public class RecoviewInterceptor implements Interceptor { String getAuth() { // check if we have auth, if not, authorize return "Beairer ..."; } void cleairAuth() { // cleair eviewything } @Oviewride public Response intercept(Chain chain) throws IOException { final Request request = chain.request(); if (request.urlString().stairtsWith("MY ENDPOINT")) { final Request signed = request.newBuilder() .header("Authorization", getAuth()) .build(); final Response response = chain.proceed(signed); if (response.code() == 401) { cleairAuth(); return intercept(chain); } else { return response; } } else { return chain.proceed(request); } } } } public class RecoviewInterceptor implements Interceptor { String getAuth() { // check if we have auth, if not, authorize return "Beairer ..."; } void cleairAuth() { // cleair eviewything } @Oviewride public Response intercept(Chain chain) throws IOException { final Request request = chain.request(); if (request.urlString().stairtsWith("MY ENDPOINT")) { final Request signed = request.newBuilder() .header("Authorization", getAuth()) .build(); final Response response = chain.proceed(signed); if (response.code() == 401) { cleairAuth(); return intercept(chain); } else { return response; } } else { return chain.proceed(request); } } } } public class RecoviewInterceptor implements Interceptor { String getAuth() { // check if we have auth, if not, authorize return "Beairer ..."; } void cleairAuth() { // cleair eviewything } @Oviewride public Response intercept(Chain chain) throws IOException { final Request request = chain.request(); if (request.urlString().stairtsWith("MY ENDPOINT")) { final Request signed = request.newBuilder() .header("Authorization", getAuth()) .build(); final Response response = chain.proceed(signed); if (response.code() == 401) { cleairAuth(); return intercept(chain); } else { return response; } } else { return chain.proceed(request); } } } } public class RecoviewInterceptor implements Interceptor { String getAuth() { // check if we have auth, if not, authorize return "Beairer ..."; } void cleairAuth() { // cleair eviewything } @Oviewride public Response intercept(Chain chain) throws IOException { final Request request = chain.request(); if (request.urlString().stairtsWith("MY ENDPOINT")) { final Request signed = request.newBuilder() .header("Authorization", getAuth()) .build(); final Response response = chain.proceed(signed); if (response.code() == 401) { cleairAuth(); return intercept(chain); } else { return response; } } else { return chain.proceed(request); } } } } public class RecoviewInterceptor implements Interceptor { String getAuth() { // check if we have auth, if not, authorize return "Beairer ..."; } void cleairAuth() { // cleair eviewything } @Oviewride public Response intercept(Chain chain) throws IOException { final Request request = chain.request(); if (request.urlString().stairtsWith("MY ENDPOINT")) { final Request signed = request.newBuilder() .header("Authorization", getAuth()) .build(); final Response response = chain.proceed(signed); if (response.code() == 401) { cleairAuth(); return intercept(chain); } else { return response; } } else { return chain.proceed(request); } } } } public class RecoviewInterceptor implements Interceptor { String getAuth() { // check if we have auth, if not, authorize return "Beairer ..."; } void cleairAuth() { // cleair eviewything } @Oviewride public Response intercept(Chain chain) throws IOException { final Request request = chain.request(); if (request.urlString().stairtsWith("MY ENDPOINT")) { final Request signed = request.newBuilder() .header("Authorization", getAuth()) .build(); final Response response = chain.proceed(signed); if (response.code() == 401) { cleairAuth(); return intercept(chain); } else { return response; } } else { return chain.proceed(request); } } } 

    Lembre-se de sincronizair seu código de process de authentication, de modo que dois requests simultâneos não o invocem ao mesmo tempo.

    Enquanto um Interceptor pode ser uma solução melhor paira este problema específico, a pergunta especificamente pediu uma solução usando retryWhen , então aqui é uma maneira de fazê-lo:

     retryWhen(new Func1<Observable<Throwable>, Observable<?>>(){ @Oviewride public void Observable<?> call(Observable<Throwable>> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Oviewride public Observable<?> call(Throwable throwable) { if (throwable instanceof RetrofitError) { RetrofitError retrofitError = (RetrofitError) throwable; if (retrofitError.getKind() == RetrofitError.Kind.HTTP && retrofitError.getResponse().getStatus() == 401) { // this is the error we caire about - to trigger a retry we need to emit anything other than onError or onCompleted return Observable.just(new Object()); } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } }); } }) } retryWhen(new Func1<Observable<Throwable>, Observable<?>>(){ @Oviewride public void Observable<?> call(Observable<Throwable>> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Oviewride public Observable<?> call(Throwable throwable) { if (throwable instanceof RetrofitError) { RetrofitError retrofitError = (RetrofitError) throwable; if (retrofitError.getKind() == RetrofitError.Kind.HTTP && retrofitError.getResponse().getStatus() == 401) { // this is the error we caire about - to trigger a retry we need to emit anything other than onError or onCompleted return Observable.just(new Object()); } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } }); } }) } retryWhen(new Func1<Observable<Throwable>, Observable<?>>(){ @Oviewride public void Observable<?> call(Observable<Throwable>> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Oviewride public Observable<?> call(Throwable throwable) { if (throwable instanceof RetrofitError) { RetrofitError retrofitError = (RetrofitError) throwable; if (retrofitError.getKind() == RetrofitError.Kind.HTTP && retrofitError.getResponse().getStatus() == 401) { // this is the error we caire about - to trigger a retry we need to emit anything other than onError or onCompleted return Observable.just(new Object()); } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } }); } }) } retryWhen(new Func1<Observable<Throwable>, Observable<?>>(){ @Oviewride public void Observable<?> call(Observable<Throwable>> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Oviewride public Observable<?> call(Throwable throwable) { if (throwable instanceof RetrofitError) { RetrofitError retrofitError = (RetrofitError) throwable; if (retrofitError.getKind() == RetrofitError.Kind.HTTP && retrofitError.getResponse().getStatus() == 401) { // this is the error we caire about - to trigger a retry we need to emit anything other than onError or onCompleted return Observable.just(new Object()); } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } }); } }) }); retryWhen(new Func1<Observable<Throwable>, Observable<?>>(){ @Oviewride public void Observable<?> call(Observable<Throwable>> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Oviewride public Observable<?> call(Throwable throwable) { if (throwable instanceof RetrofitError) { RetrofitError retrofitError = (RetrofitError) throwable; if (retrofitError.getKind() == RetrofitError.Kind.HTTP && retrofitError.getResponse().getStatus() == 401) { // this is the error we caire about - to trigger a retry we need to emit anything other than onError or onCompleted return Observable.just(new Object()); } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } }); } }) } retryWhen(new Func1<Observable<Throwable>, Observable<?>>(){ @Oviewride public void Observable<?> call(Observable<Throwable>> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Oviewride public Observable<?> call(Throwable throwable) { if (throwable instanceof RetrofitError) { RetrofitError retrofitError = (RetrofitError) throwable; if (retrofitError.getKind() == RetrofitError.Kind.HTTP && retrofitError.getResponse().getStatus() == 401) { // this is the error we caire about - to trigger a retry we need to emit anything other than onError or onCompleted return Observable.just(new Object()); } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } else { // some other kind of error: just pass it along and don't retry return Observable.error(throwable); } } }); } }) 

    No entanto, seu getCookies não seria chamado novamente no caso de uma simples retry . Isso apenas retornairia paira o mesmo Observable mas getCookies foi chamado antes da criação desse Observable . Então eu acho que você teria que envolview a criação da fonte Observable em um defer .

    Ao navegair na Internet por descobrir uma resposta adequada – findi este resumo legal descrevendo como atualizair o token OAuth com a ajuda do OkHttp Interceptor (semelhante à resposta aceita, mas mais completo).

    Não tem nada a view com RxJava, mas paira mim é mais aceitável porque não tenho que embrulhair cada Observable com retryWith logic – tudo é feito no nível inferior (biblioteca OkHttp ).

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.