2016-04-25 11 views
5

に私は私のアプリで複数のネットワーク呼び出しを持っています。私は、この変圧器でコン演算子を使用してIOスレッドでネットワーク要求を実行したい:適用スケジューラは二度(コンを使用して)観察可能なチェーン

public static <T> Transformer<T, T> runOnIoThread() 
{ 
    return tObservable -> tObservable.subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()); 
} 

これは、限り、私は、単一のネットワーク呼び出しを持っているとうまく動作するようです。しかし、私が次の例のようにチェーン化すれば、私はAndroidのNetworkInMainThreadExceptionを取得しています。

public Observable<String> networkCall1() 
{ 
    return <NETWORK_CALL_1()> 
      .compose(runOnIoThread()); 
} 

public Observable<String> networkCall2(String input) 
{ 
    return <NETWORK_CALL_2(input)> 
      .compose(runOnIoThread()); 
} 

public Observable<String> chainedCalls() 
{ 
    return networkCall1() 
      .flatMap(result1 -> networkCall2(result1)); 
} 

私の考えは、前composeは、呼び出しの前に完全に観察可能なチェーンに適用され、その後のcompose呼び出しは、以前の1の行動を「上書き」というものでした。しかし、実際には、それは最初composeobserveOnコール(observeOnメインスレッド)のように見えるが二composeコール(subscribeOn IOスレッド)を支配します。 1つの明白な解決策は、networkCall1の2つのバージョンを持つことです - スケジューラを適用するものとそうでないものがあります。しかし、これは私のコードをかなり冗長にするでしょう。

は、あなたがよりよい解決策を知っていますか? 観測可能なチェーンにスケジューラを2回(作成して)適用する動作を説明できますか?

編集:ネットワークコールにRxJavaを使用しています。

答えて

7

あなただけのストリームに一回subscribeOn()を使用することができます。それをもう一度使用すると、何もしません。あなたが一緒にあなたの二つの方法を連鎖しているときのような、あなたは実行します。メインスレッドへの上に動作を切り替える

observeOn(AndroidSchedulers.mainThread())

を。その後、次のsubscribeOn()が効果的に無視されるため、そこにとどまります。

私はあなたが実際にあなたのコン方法で物事を過度に複雑されていることを示唆しています。ただ、両方のネットワークの呼び出しに

subscribeOn(Schedulers.io())

を追加し、あなたがメインスレッド上で結果を処理する直前に

observeOn(AndroidSchedulers.mainThread())

を使用しています。あなたのようなもので終わるだろう:

public Observable<String> networkCall1() 
{ 
    return <NETWORK_CALL_1()> 
      .subscribeOn(Schedulers.io); 
} 

public Observable<String> networkCall2(String input) 
{ 
    return <NETWORK_CALL_2(input)> 
      .subscribeOn(Schedulers.io); 
} 

public Observable<String> chainedCalls() 
{ 
    return networkCall1() 
      .flatMap(result1 -> networkCall2(result1)) 
      .observeOn(AndroidSchedulers.mainThread()); 
} 

EDIT

あなたもし本当にすることができます個々のネットワーク呼び出し方法にobserveOn()電話を持っていると思います。 chainedCalls()メソッドには、追加のobserveOn()を追加する必要があります。ストリームごとに好きなだけ多くの電話番号をobserveOn()個持つことができます。それは次のようなものです:

public Observable<String> networkCall1() 
{ 
    return <NETWORK_CALL_1()> 
      .subscribeOn(Schedulers.io) 
      .observeOn(AndroidSchedulers.mainThread()); 
} 

public Observable<String> networkCall2(String input) 
{ 
    return <NETWORK_CALL_2(input)> 
      .subscribeOn(Schedulers.io) 
      .observeOn(AndroidSchedulers.mainThread()); 
} 

public Observable<String> chainedCalls() 
{ 
    return networkCall1() 
      .observeOn(Schedulers.io) 
      .flatMap(result1 -> networkCall2(result1)) 
      .observeOn(AndroidSchedulers.mainThread()); 
} 
+0

こんにちはJahnold!ありがとうございました!あなたの説明は、私がsubscribeOn、observeOn、およびcomposeをよく理解する助けになりました。 私のメソッドはライブラリの一部になるので、できるだけ簡単に呼び出しを行いたい(つまり、observeOn呼び出しを省略する)。 JackWhartonはここに書いています(http:// stackoverflow。IO /バックグラウンドスレッドで呼び出しを実行し、observeOnが呼び出し元のスレッド上にあるRxJavaを使用したRetrofitについての最新情報(com/a/21010181/2011622)しかし、2つの改造コールを連鎖させることはまだ可能です。だから、そうする方法がなければならないのですよね? –

+0

私は本当にあなたがすべての呼び出しの一部であることを望む場合、余分な 'observeOn'をどのように使うことができるかを示す答えを更新しました。 – Jahnold

+1

ellaboratingありがとう!したがって、 'subscribeOn'はストリーム' observeOn'で複数回使用して別のスレッドに切り替えることができます。私はその情報をドキュメントで見つけることができませんでした。どうやってそれを知ったのですか?あなたはリファレンスがありますか? –

関連する問題