23

我对 RxJava 还很陌生,所以这可能是一个愚蠢的问题。我将描述我的场景。

我在 UI 线程上运行了一些代码,它们将更新一些图像,但这些图像不是很重要,它们在生成它们时会消耗一些资源,所以我想在单个线程上生成它们(当然不是 UI 线程)和一一生成。我猜蹦床调度程序是我想要的,但我的问题是,如果我使用它,那么它会在 UI 线程上完成工作,我希望它在另一个线程上完成。

显然我可以编写自己的线程,我可以在其中对项目进行排队,然后逐个处理这些项目,但我认为 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()。我仍在测试,但我认为它可以满足我发布此内容时的要求。

4

3 回答 3

17

Scheduler您可以通过以下Observable方式之一创建单个可重用线程来创建一个:

  • 创建一个ThreadPoolExecuter池大小为 1 的 a(Executors.newSingleThreadExecutor()这是一种方便的静态工厂方法),然后使用它通过该Schedulers.from()方法生成调度程序。
  • RxAndroid提供了一个自定义Scheduler实现,它使用 aHandler来安排动作,因此可以通过将其传递给工厂方法来与Thread任何Looper运行的程序一起使用。HandlerAndroidSchedulers.handlerThread()

请注意,Scheduler如果您在这些任务结束时与 UI 交互,则需要在主线程上进行观察。

于 2015-04-18T19:05:32.187 回答
16

在 RxJava 2 中,您可以使用Schedulers.single()

返回一个默认的、共享的、单线程支持的调度程序实例,用于需要在同一后台线程上强顺序执行的工作。

有关详细信息,请参阅文档。

我在 RxJava 1 Schedulers 文档中看不到它。

于 2017-04-08T19:44:40.873 回答
0

您正在使用trampoline调度程序,因此这意味着您的源 observable 将在当前线程(这里是主线程)上运行。

subscribeOn将适用于上游和下游。这就是为什么您的日志显示您正在运行main thread

要解决此问题,您可以Schedulers.single()在 中使用subscribeOn,然后observeOn在主线程中使用。

于 2019-08-25T10:12:23.290 回答