2016-06-28 9 views
1

を組み合わせることで、次のスニペットを持っていない:二つの異なる観測

Log.d("#######", Thread.currentThread().getName()); 
    RxSearchView.queryTextChangeEvents(searchView) 
      .debounce(400, TimeUnit.MILLISECONDS,Schedulers.newThread()) 
      .flatMap(new Func1<SearchViewQueryTextEvent, Observable<GifsData>>() { 
       @Override 
       public Observable<GifsData> call(SearchViewQueryTextEvent txtChangeEvt) { 
        return RestWebClient.get().getSearchedGifs(txtChangeEvt.queryText().toString(),"dcJmzC"); 
       } 
      }) 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Observer<GifsData>() { 
       @Override 
       public void onCompleted() { 
        Log.d("#######","onCompleted searchGifs"); 
       } 

       @Override 
       public void onError(Throwable e) { 
        Log.d("#######",e.toString()); 
       } 

       @Override 
       public void onNext(GifsData gifsData) { 
        mainFragmentPresenterInterface.displaySearchedGifsList(gifsData); 
       } 
      }); 
} 

どんなに私は、次のエラーを取得維持しようとするもの:

java.lang.IllegalStateException: Must be called from the main thread. Was: Thread[RxNewThreadScheduler-2,5,main] 

はおそらくthis..Havenに時間近くを費やしてきました問題が何かを理解することができました。でも、次のリンクに私のスニペットを照合しようとした:

Combine RxTextView Observable and Retrofit Observable

ありません運を。誰かがここで間違っていることを指摘できますか?

ありがとうございました。

+2

この行を削除します。「.subscribeOn(Schedulers.newThread())」は正しく動作します。あなたはバックグラウンドスレッドのビューにアクセスしています。または、Observable以外の検索テキストをフェッチして、バックグラウンドスレッドでビューにアクセスしないようにすることもできます。 –

+0

しかし、私は主なスレッド上でそれを観察しています。これは、ビューが操作されている場所ではありません。 – user2511882

+0

例外は表示されません。しかし、onNextはいずれも起動されません。 – user2511882

答えて

2

エラーの理由:バックグラウンドスレッドで購読していて、バックグラウンドスレッドでストリームを見ることにアクセスしています。ここで私はそれがあなたのために働くだろうこれを試して、バックグラウンドスケジューラしなさい上RestWebClient.get().getSearchedGifs(txtChangeEvt.queryText().toString(),"dcJmzC").subscribeOn(Schedulers.newThread());を呼び出しています

RxSearchView.queryTextChangeEvents(mSearchView) 
      .debounce(400, TimeUnit.MILLISECONDS) 
      .flatMap(new Func1<SearchViewQueryTextEvent, Observable<String>>() { 
       @Override 
       public Observable<String> call(SearchViewQueryTextEvent txtChangeEvt) { 
        return Observable.just(txtChangeEvt.queryText().toString()).subscribeOn(AndroidSchedulers.mainThread()); 
       } 
      }) 
      .flatMap(new Func1<GifsData, Observable<String>>() { 
       @Override 
       public Observable<GifsData> call(String txtChangeEvt) { 
        return RestWebClient.get().getSearchedGifs(txtChangeEvt,"dcJmzC").subscribeOn(Schedulers.newThread()); 
       } 
      }) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Observer<GifsData>() { 
       @Override 
       public void onCompleted() { 
        Log.d("#######","onCompleted searchGifs"); 
       } 

       @Override 
       public void onError(Throwable e) { 
        Log.d("#######",e.toString()); 
       } 

       @Override 
       public void onNext(GifsData gifsData) { 
        Log.d("#######", gifsData); 
       } 
      }); 

それは、computationスケジューラを使用して、あなたがメインにそれを変更する必要があり、デフォルトではオペレータdebounce

+0

ここには2つのsubscribeOnがある。それは問題を引き起こさないでしょう。私の理解によれば、最初のsubscribeOnだけがデータストリームに適用されます。その場合、getSearchedGifs呼び出しはmainThreadで実行されます。それじゃない? – user2511882

+0

異なる加入者でストリームを購読することができます。異なる加入者に異なるストリーム加入者を持つことは、まったく正しいことです。他の誰かがあなたのコメントに返信することを願っています –

+0

私は、flatmapped observablesで複数のsubscribeOnが動作する理由について、次のリンクを発見しました。しかし、説明はまだ私のために複雑です。私はそれが正しい方向にあると思われるので、答えをupvoteしますが、なぜ誰かがflatmappingでsubscribeOnが動作する理由を教えてくれるまでそれを開いたままにしておきます。リンク:https://groups.google.com/forum/#!topic/rxjava/XXJJPhn8PHQ – user2511882

0

を助けている場合、私に教えてくださいあなたがUI上でのみメインで作業しているからです。

次に、ioスケジューラで実行されるネットワーク要求をスケジュールすることです。 (現在は1つだけsubscribeOnを使用しています)。

また、UIと反応しないようにメインスレッドの結果を観察します。

RxSearchView.queryTextChangeEvents(searchView) 
    .debounce(400, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()) 
    .flatMap(new Func1<SearchViewQueryTextEvent, Observable<GifsData>>() { 
    @Override 
    public Observable<GifsData> call(SearchViewQueryTextEvent txtChangeEvt) { 
     return RestWebClient.get() 
     .getSearchedGifs(txtChangeEvt.queryText().toString(),"dcJmzC") 
     .subscribeOn(Schedulers.io()); 
    } 
    }) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(new Observer<GifsData>() { 
    @Override 
    public void onCompleted() { 
     Log.d("#######","onCompleted searchGifs"); 
    } 

    @Override 
    public void onError(Throwable e) { 
     Log.d("#######",e.toString()); 
    } 

    @Override 
    public void onNext(GifsData gifsData) { 
     mainFragmentPresenterInterface.displaySearchedGifsList(gifsData); 
    } 
}); 
関連する問題