私は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()
を使用できます。私はまだテスト中ですが、これを投稿したときにやりたかったことを実行すると思います。
次のいずれかの方法で、Scheduler
のObservable
を作成する単一の再利用可能なスレッドを作成できます。
ThreadPoolExecuter
を作成し(Executors.newSingleThreadExecutor()
はこれを行うのに便利な静的ファクトリメソッドです)、それを使用してSchedulers.from()
メソッドを介してスケジューラを生成します。Scheduler
を使用してアクションをスケジュールするカスタムHandler
実装を提供します。したがって、Thread
をAndroidSchedulers.handlerThread()
ファクトリメソッドに渡すことにより、Looper
が実行されている任意のHandler
で使用できます。 。これらのタスクの最後にUIを操作している場合は、メインスレッドScheduler
を観察する必要があることに注意してください。
RxJava 2では、次のSchedulers.single()
を使用できます。
同じバックグラウンドスレッドで強力なシーケンシャル実行を必要とする作業に対して、デフォルトの共有シングルスレッドバックアップスケジューラインスタンスを返します。
詳細は ドキュメントを参照 をご覧ください。
RxJava 1 Schedulersのドキュメント で利用できないようです。
trampoline
スケジューラーを使用しているため、ソースオブザーバブルが現在のスレッド(ここではメインスレッドです)で実行されます。
そしてsubscribeOn
は上流と下流の両方で機能します。ログが_main thread
_で実行されていることをログに表示する理由
これを修正するには、subscribeOn
でSchedulers.single()
を使用し、次にメインスレッドでobserveOn
を使用します。