Планировщик одиночных потоков RxJava
Я новичок в RxJava, так что это, наверное, немой вопрос. Я расскажу о своем сценарии.
У меня есть некоторый код, запущенный в потоке пользовательского интерфейса, который будет обновлять некоторые изображения, но эти изображения не очень важны, и они потребляют немного ресурсов при их создании, поэтому я хочу сгенерировать их в одном потоке (а не в потоке пользовательского интерфейса курс) и генерировать их один за другим. Я предполагаю, что планировщик трамплинов - это то, что я хочу, но моя проблема в том, что если я его использую, то он работает над потоком пользовательского интерфейса, и я хочу, чтобы он делал это в другом потоке.
Очевидно, я могу написать свой собственный поток, в котором я могу помещать в очередь элементы, а затем обрабатывает их один за другим, но я подумал, может быть, у 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 thread?" всегда имеет значение true. Итак, как я могу сделать этот код и все последующие попытки сделать то же самое, что и в одном потоке (а не в потоке ui), чтобы не писать кучу кода для работы в очереди?
Edit:
Я считаю, что теперь это можно выполнить с помощью Schedulers.single()
, или если вы хотите использовать свой собственный, вы можете использовать new SingleScheduler()
. Я все еще тестирую, но я думаю, что он делает то, что мне нужно, когда я разместил это.
Ответы
Ответ 1
Вы можете создать один многоразовый поток для создания Scheduler
для Observable
одним из следующих способов:
- Создайте
ThreadPoolExecuter
с размером пула 1 (Executors.newSingleThreadExecutor()
- это удобный статический метод factory для этого), а затем используйте его для генерации планировщиков с помощью метода Schedulers.from()
.
- RxAndroid предоставляет пользовательскую реализацию
Scheduler
, которая использует Handler
для планирования действий и, следовательно, может использоваться с любыми Thread
, который имеет Looper
, запущенный, передав его Handler
методу AndroidSchedulers.handlerThread()
factory.
Обратите внимание, что вам нужно будет наблюдать в основном потоке Scheduler
, если вы будете взаимодействовать с пользовательским интерфейсом при завершении этих задач.
Ответ 2
В RxJava 2 вы можете использовать Schedulers.single()
, который:
Возвращает стандартный экземпляр планировщика по умолчанию, общий и однопоточный. работа, требующая строгого последовательного выполнения на том же фоне нить.
Подробнее см. в документации.
Я не вижу его доступным в RxJava 1 Документация планировщиков.
Ответ 3
Вы используете планировщик trampoline
, так что это означает, что ваша исходная наблюдаемая будет запущена в текущем потоке (здесь основной поток).
И subscribeOn
будет работать как для восходящего, так и для нисходящего потоков. Вот почему ваш журнал показывает, что вы работаете на main thread
Чтобы это исправить, вы можете использовать Schedulers.single()
в subscribeOn
, а затем observeOn
в основном потоке.