android - 在 Rx 链中多次切换线程

标签 android rx-java rx-java2

假设我有以下 Android 案例:

  1. 从网络请求组列表
  2. 为每个组显示一些 UI 元素
  3. 为每个组请求项目
  4. 显示 UI 元素 每一项

我想用 RxJava 来做这个:

webService.requestGroups()
        .flatMap(group -> {
            view.showGroup(group);
            return webService.requestItems(group);
        })
        .toList()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())

        .subscribe(items -> view.showItems(items));

如您所见,我有 2 个 View 对象调用,每个调用都必须在主线程上执行。以及 2 个 webService 调用,必须在后台线程上执行。

此代码的问题:第一次调用 View 将在后台执行,这会导致 Android RuntimeException(只有原始线程可能会接触 View 或其他东西)如果我将 .observeOn 转移到链的开头- 第二个 webService 调用将在主线程中执行。

如何在 RxJava 链中多次“游过”线程?

最佳答案

来自Rx doc for SubscribeOn :

The SubscribeOn operator designates which thread the Observable will begin operating on, no matter at what point in the chain of operators that operator is called. ObserveOn, on the other hand, affects the thread that the Observable will use below where that operator appears. For this reason, you may call ObserveOn multiple times at various points during the chain of Observable operators in order to change on which threads certain of those operators operate.

SubscribeOn 运算符只能应用一次并设置起始线程。 ObserveOn 可用于在流中的任意点从一个线程转到另一个线程。所以我认为以下应该做你想做的:

webService.requestGroups()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(group -> {
        view.showGroup(group);
        return webService.requestItems(group)
                         .subscribeOn(Schedulers.io());
    })
    .toList()
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(items -> view.showItems(items));

但在我看来这太复杂了。我会订阅第一个可观察对象,然后为每个组启动一个新链,如下所示:

webService.requestGroups()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(group -> { 
        view.showGroup(group);
        webService.requestItems(group)
            .subscribeOn(Schedulers.io()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(items -> view.showItems(items));
    });

关于android - 在 Rx 链中多次切换线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46070235/

相关文章:

android - 在 Visual Studio Code 中找不到参数的方法 flutter()

android - 如何在 Android 中使用未知加密算法连接到 WiFi 网络?

android - 将 Observable<Observable<Cursor>> 扁平化为 Observable<Cursor>

java - RxJava2 - 订阅的消费者抛出异常

android - RxJava - 何时以及为何使用 Observable.share()

android - onCreate 之外的 TextView.setText 不起作用

android - org.apache.http.client.methods

android - MVVM。如何将复杂的数据/命令从域传输到 View

java - 如何断言 Completable 是否已被订阅/完成 (RxJava2)

java - 为什么RxJava2不支持 "Maybe.doOnDispose"?