【问题标题】:RxJava single background thread schedulerRxJava 单后台线程调度器
【发布时间】:2015-06-24 14:45:08
【问题描述】:

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

我在 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()。我仍在测试,但我认为它可以满足我发布此内容时的要求。

【问题讨论】:

  • 我已经在使用 RxAndroid 并且我的代码显示我正在使用subscribeOn。我只是不知道将什么传递给subscribeOn 来做我想做的事。
  • 您需要订阅后台线程SchedulerSchedulers class 包含用于创建它们的静态工厂方法)。然后你需要在主线程Scheduler上观察,可以在RxAndroid中通过AndroidSchedulers.mainThread()方法获取。
  • 我明白了,但是哪个Scheduler 会给我一个后台线程,它会像trampoline 调度程序一样继续重复使用?
  • 您可以创建一个池大小为 1 (Executors.newSingleThreadExecutor()) 的 ThreadPoolExecuter,然后通过 Schedulers.from() 方法使用它来生成调度程序。或者,您可以创建一个自定义Thread 并运行Looper(例如HandlerThread),并将在该Looper 上运行的Handler 传递给AndroidSchedulers.handlerThread() 方法以获得将运行的Scheduler在那个线程上。

标签: java android rx-java rx-android


【解决方案1】:

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

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

上运行

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

【讨论】:

    【解决方案2】:

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

    返回一个默认的、共享的、单线程支持的调度程序实例 需要在同一背景下强顺序执行的工作 线程。

    see the documentation了解更多详情。

    我没有看到它在 RxJava 1 Schedulers documentation 中可用。

    【讨论】:

    • 但是 single() 不是总是返回相同的调度程序吗?因此,如果您使用 single() 有 2 个不同的项目,它们将共享同一个线程,对吗?所以这不能回答问题,因为线程不会专门用于工作
    • @FrankMonza 当然single() 总是返回相同的线程,因为您希望工作是按顺序进行的(这就是重点)。如果您想要两个独立的单线程调度程序,请使用 Schedulers.from(Executor executor),如另一个答案中所述。
    【解决方案3】:

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

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

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

    【讨论】:

    • 我错过了 rxjava 中的 Schedulers.singleThread() 方法,就像它的 newThread() 一样。
    • @AlvaroGutierrezPerez RxJava 2 有一个新的Schedulers.single()
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多