2015-08-19 14 views
6

Sto usando RxJava e RxBindings per la visualizzazione in Android. di seguito è un esempio di ciò che sto facendo.RxJava/RxBinding: come gestire gli errori su RxView

RxView.clicks(btMyButton).flatMap(btn -> { 
     // another observable which can throw onError. 
     return Observable.error(null); 
    }).subscribe(object -> { 
     Log.d("CLICK", "button clicked"); 
    }, error -> { 
     Log.d("CLICK", "ERROR"); 
    }); 

quando clicco su MyButton, io uso flatMap di tornare un'altra osservabile, che è una chiamata di rete e può restituire il successo o l'errore. quando restituisce un errore lo gestisco nel blocco di errore. ma non riesco a fare nuovamente clic sul pulsante.

Come posso gestire l'errore ed essere ancora in grado di fare nuovamente clic sul pulsante?

risposta

4

Sono un po 'nuovo a RxJava, ma mi sono imbattuto in questo problema.

Il problema è che per definizione, un Observable smetterà di emettere valori quando viene chiamato il metodo error().

Per quanto posso dire, avete due opzioni:

  1. modificare il Observable che effettua la chiamata di rete in modo che quando si verifica un errore, un'eccezione non viene lanciata, ma piuttosto si ritorna un valore che indica che si è verificato un errore. In questo modo, il metodo errorable() di Observable non verrà chiamato quando si verifica un errore di rete.

  2. Cercare di utilizzare Observable.onErrorResumeNext per ignorare la terminazione dell'Osservable quando viene chiamato error(). Vedere Best practice for handling onError and continuing processing

+0

Sto usando Retrofit quindi non posso controllare la rete osservabile e sì sto usando attualmente 'onErrorResumeNext' ma il problema è che posso solo restituire un osservabile dello stesso tipo e non posso restituire nessun altro tipo di oggetto. e questo è quello che non mi piace di 'onErrorResumeNext' –

+0

Solo perché stai usando Retrofit non significa che devi usare i suoi metodi Osservabili. Puoi racchiudere una chiamata sincrona di Retrofit nel tuo Osservabile. – GreyBeardedGeek

7

GreyBeardedGeek è a posto. Per essere del tutto esplicito su una delle opzioni è possibile utilizzare .materialize():

RxView.clicks(btMyButton).flatMap(btn -> { 
     if (ok) 
      return someObservable.materialize(); 
     else 
      return Observable.error(new MyException()).materialize(); 
    }).subscribe(notification -> { 
     if (notification.hasValue()) 
      Log.d("CLICK", "button clicked"); 
     else if (notification.isOnError()) 
      Log.d("CLICK", "ERROR"); 
    }); 

Tra l'altro non passano null per Observable.error().

+0

certo, proverò questa opzione e vedrai. e sì null era solo per questo esempio :) –

1

utilizzare approccio simile a già descritto:

RxView.clicks(btMyButton) 
    .flatMap(btn -> { 
    // another observable which can throw onError. 
    return Observable.error(null) 
     .doOnError(error -> { 
     //handle error 
     }) 
     .onErrorResumeNext(Observable.empty());//prevent observable from terminating 
    }) 
    .subscribe(object -> { 
     Log.d("CLICK", "button clicked");//here no errors should occur 
    }); 

Ho una short article che descrive questo approccio.

Problemi correlati