web-dev-qa-db-ja.com

RxJavaシングルバックグラウンドスレッドスケジューラ

私はRxJavaにかなり慣れていないので、これはおそらく馬鹿げた質問です。私のシナリオについて説明します。

一部の画像を更新するいくつかのコードをUIスレッドで実行していますが、それらの画像はそれほど重要ではなく、生成中に少しのリソースを消費するため、単一のスレッド(もちろんUIスレッドではない)で生成したいと思います。それらを1つずつ生成します。私が望むのはトランポリンスケジューラーだと思いますが、私の問題は、それを使用すると、UIスレッドで機能し、別のスレッドでも機能することです。

もちろん、アイテムをキューに入れることができる独自のスレッドを記述して、それらを1つずつ処理することもできますが、RxJavaには簡単な解決策があると思いますか?

私の現在のコードは次のようになります:

_Observable<Bitmap> getImage = Observable.create(new Observable.OnSubscribe<Bitmap>() {
    @Override public void call(Subscriber<? super Bitmap> subscriber) {
        Log.w(TAG,"On ui thread? "+ UIUtils.isRunningOnUIThread());
        subscriber.onNext(doComplexTaskToGetImage());
        subscriber.onCompleted();
    }
});

getImage.subscribeOn(Schedulers.trampoline()).subscribe(new Action1<Bitmap>() {
    @Override public void call(Bitmap bitmap) {
        codeToSetTheBitmap(bitmap);
    }
});
_

「UIスレッド上」と書かれたログ常に本当です。それで、そのコードを実行し、同じことを実行するためのすべての試行を、(uiスレッドではなく)単一のスレッドで実行して、その作業をキューに入れるコードの束を書かずにするにはどうすればよいですか?

編集:

これはSchedulers.single()を使用して実現できると思います。または、独自の機能が必要な場合はnew SingleScheduler()を使用できます。私はまだテスト中ですが、これを投稿したときにやりたかったことを実行すると思います。

19
casolorz

次のいずれかの方法で、SchedulerObservableを作成する単一の再利用可能なスレッドを作成できます。

  • プールサイズが1のThreadPoolExecuterを作成し(Executors.newSingleThreadExecutor()はこれを行うのに便利な静的ファクトリメソッドです)、それを使用してSchedulers.from()メソッドを介してスケジューラを生成します。
  • RxAndroid は、Schedulerを使用してアクションをスケジュールするカスタムHandler実装を提供します。したがって、ThreadAndroidSchedulers.handlerThread()ファクトリメソッドに渡すことにより、Looperが実行されている任意のHandlerで使用できます。 。

これらのタスクの最後にUIを操作している場合は、メインスレッドSchedulerを観察する必要があることに注意してください。

14
corsair992

RxJava 2では、次のSchedulers.single()を使用できます。

同じバックグラウンドスレッドで強力なシーケンシャル実行を必要とする作業に対して、デフォルトの共有シングルスレッドバックアップスケジューラインスタンスを返します。

詳細は ドキュメントを参照 をご覧ください。

RxJava 1 Schedulersのドキュメント で利用できないようです。

12

trampolineスケジューラーを使用しているため、ソースオブザーバブルが現在のスレッド(ここではメインスレッドです)で実行されます。

そしてsubscribeOnは上流と下流の両方で機能します。ログが_main thread_で実行されていることをログに表示する理由

これを修正するには、subscribeOnSchedulers.single()を使用し、次にメインスレッドでobserveOnを使用します。

0
Trieu Tran