Планировщик одиночных потоков 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 в основном потоке.