2016-06-27 12 views
0

rxJavaでログインフォームを作成して改造したいと思います。サーバーを要求している間、私はエラーを得た場合でも、退会はRXrxJavaとRetrofitで繰り返し要求するログインフォーム

の底から呼び出された私は、私は fun authorize(email:String, pass:String): Observable<Unit>

レトロフィット によって実施される方法を登録してい

fun validEmail(): Observable<CharSequence> //last well formated login 
fun validPassword(): Observable<CharSequence> //last password of length 
fun clicks(): Observable<Unit> //clicks on login buttons 

libにrxAndroidBindingによって実装されたUIのメソッドを持っています入力が有効でログインボタンがクリックされている場合は、リクエストを行いたいと考えています。

`` `

val validPair = rx.Observable.combineLatest(iView.validEmail(), iView.validPassword(), ::ValidLoginPair) 
      .doOnNext { iView.setLoginButtonEnabled(true) } 

    subscription = rx.Observable.combineLatest(validPair, iView.clicks(), { pair, unit -> pair }) 
      .doOnNext { iView.setProgress(true) } 
      .flatMap { 
       model.get().authorize(it.email.toString(), it.password.toString()) 
         .observeOn(AndroidSchedulers.mainThread()) 
         .doOnError { 
          it.printStackTrace(); 
          iView.setProgress(false); 
          iView.showError("NetWorkError", it.message ?: "Unknown error") 
         } 
      } 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe({ 
       iView.setProgress(false); 
       iView.onLogin() 
      }) {it.printStackTrace(); iView.setProgress(false);} 

`` `

私は200応答を得た場合、それが動作します。しかし、onErrorが呼び出されると、すべてのuiイベントのサブスクリプションはサブスクライブされなくなります。 2回目のクリックで何も起こりません。 私は間違っていますか?なぜ改装はそのように機能するのですか? ReactiveX documentationから


バージョン compile 'io.reactivex:rxandroid:1.2.1' compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'io.reactivex:rxjava:1.1.6'

添えスタック

java.lang.Thread.State: WAITING 
    at com.jakewharton.rxbinding.widget.TextViewAfterTextChangeEventOnSubscribe$2.onUnsubscribe(TextViewAfterTextChangeEventOnSubscribe.java:40) 
    at rx.android.MainThreadSubscription.unsubscribe(MainThreadSubscription.java:72) 
    at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124) 
    at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113) 
    at rx.Subscriber.unsubscribe(Subscriber.java:98) 
    at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124) 
    at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113) 
    at rx.Subscriber.unsubscribe(Subscriber.java:98) 
    at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124) 
    at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113) 
    at rx.Subscriber.unsubscribe(Subscriber.java:98) 
    at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124) 
    at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113) 
    at rx.Subscriber.unsubscribe(Subscriber.java:98) 
    at rx.internal.operators.OnSubscribeCombineLatest$LatestCoordinator.cancel(OnSubscribeCombineLatest.java:178) 
    at rx.internal.operators.OnSubscribeCombineLatest$LatestCoordinator.unsubscribe(OnSubscribeCombineLatest.java:165) 
    at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124) 
    at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113) 
    at rx.Subscriber.unsubscribe(Subscriber.java:98) 
    at rx.internal.operators.OnSubscribeCombineLatest$LatestCoordinator.cancel(OnSubscribeCombineLatest.java:178) 
    at rx.internal.operators.OnSubscribeCombineLatest$LatestCoordinator.unsubscribe(OnSubscribeCombineLatest.java:165) 
    at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124) 
    at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113) 
    at rx.Subscriber.unsubscribe(Subscriber.java:98) 
    at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124) 
    at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113) 
    at rx.Subscriber.unsubscribe(Subscriber.java:98) 
    at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:814) 
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:573) 
    at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:562) 
    at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:846) 
    at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:72) 
    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:276) 
    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:219) 
    at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5254) 
    at java.lang.reflect.Method.invoke(Method.java:-1) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

答えて

1

観測がゼロ以上OnNext通知を行うことができる、単を表す各 が放出しますアイテム、およびOnCompleted通知またはOnError通知( )のいずれかによってそれらの通知を受け取り、その両方には通知しません。 OnCompletedまたはOnError 通知を発行すると、それ以降通知は発行されません。ネットワークエラーまたはAPIエラー(範囲200~300外コード)がある場合

補強はonErrorを呼び出します。 onErrorへの呼び出しの後、Observableは終了します。

私の例ではJavaを使用して申し訳ありません

が、1つの解決策は次のようになります。

authorize(username, password).flatMap(() -> Observable.just(true)) 
    .onErrorReturn(e-> Observable.just(false)) 

これはObservableは、エラーが発生した場合には終了していないことを確認します。代わりに、それは偽を出すでしょう。成功のためにはそれは本当です。ブール値を、より多くのデータを含む別のクラス(おそらくエラーメッセージ)に置き換えることができます。

注:onErrorReturnはエラーを消費します。 doOnErrorはエラーを消費せず、onErrorが呼び出されます。

+0

お返事ありがとうございます! – punksta

+0

'flatMap'の中で' onErrorReturn'を使う必要があります。そうでなければ、何も変更しません。シーケンスは、最初のエラーの後でただ完了します。 – marwinXXII

関連する問題