web-dev-qa-db-ja.com

バックグラウンドスレッドでプロセスを監視可能

ストリーム操作にRxAndroidを使用しています。私の実際の使用例では、サーバーからリストを取得しています(Retrofitを使用)。私はスケジューラを使用してバックグラウンドスレッドで作業を行い、Android UI(メイン)スレッドで最終的な放出を取得しています。

これはネットワークコールではうまく機能しますが、ネットワークコール後のオペレータはバックグラウンドスレッドを使用せず、メインスレッドで呼び出されることに気付きました。

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .subscribe(integer1 -> {});

すべての操作がバックグラウンドスレッドで実行されることを確認するにはどうすればよいですか?

20
WonderCsabo

TL; DRobserveOn(AndroidSchedulers.mainThread())filter(...)の下に移動します。


subscribeOn(...)は、Observableが動作するbeginスレッドを指定するために使用されます。 subscribeOnへの後続の呼び出しは無視されます。

したがって、次のように記述すると、everythingSchedulers.newThread()で実行されます。

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .subscribe(integer1 -> { doSomething(integer1); });

今、もちろん、これはあなたが望むものではありません:メインスレッドでdoSomethingしたいです。
ここで、observeOnが配置されます。すべてのアクションafterobserveOnは、そのスケジューラで実行されます。したがって、この例では、filterがメインスレッドで実行されます。

代わりに、observeOnsubscribeの直前に移動します。

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(integer1 -> { doSomething(integer1) });

これで、filterが「新しいスレッド」で発生し、doSomethingがメインスレッドで発生します。


さらに進むには、observeOnを複数回使用できます。

myService.fetchSomeIntegersFromServer()
        .subscribeOn(Schedulers.newThread())
        .observeOn(Schedulers.computation())
        .filter(integer -> {
            System.out.println(Looper.getMainLooper().getThread() == Thread.currentThread());
            return true;
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(integer1 -> { doSomething(integer1) });

この場合、フェッチは新しいスレッドで発生し、フィルタリングは計算スレッドで発生し、doSomethingはメインスレッドで発生します。

チェックアウト ReactiveX-SubscribeOn operator 公式ドキュメント。

57
nhaarman