为什么 onNext() 正在更新 textview,尽管 observeOn(Schedulars.io()) 在不同的线程上?

Why onNext() is updating textview, though observeOn(Schedulars.io()) on a different thread?

Observable.range(11,10).subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .subscribe(new Observer<Integer>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {

                }

                @Override
                public void onNext(@NonNull Integer integer) {
                    textView.setText(String.valueOf(integer));
                    Log.d(TAG, "onNext: "+Thread.currentThread().getName());
                }

                @Override
                public void onError(@NonNull Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });

onNext() 应该 运行 在单独的线程上,但它如何更新主线程上的 textview?

observeOn 是一个异步操作,在其处理后,推送到 onNext whixh 的结果旨在 运行 在 UI 线程上。他们正在为 us.Thats 更改线程,这不是优势吗?它是 RxJava 的特性

如果您正在使用 Data Binding Library, it allows to update the UI off the main thread.

You can change your data model in a background thread as long as it isn't a collection. Data binding localizes each variable / field during evaluation to avoid any concurrency issues.

似乎在视图生命周期的最开始,有一个非常短的时间跨度,您可以在其中更改主线程的视图。

当您直接在 onCreate() 中从主线程启动一个线程时,该线程几乎立即 returns 结果(因为没有真正的工作要做)您不会得到CalledFromWrongThreadException调整视图时。

如果你有一个短暂的延迟(可能在你的机器上是不同的)——对我来说,50ms 就足够了——在线程/Observable 中的工作开始之前,你会看到预期的 CalledFromWrongThreadException.

Observable.just("first")
  .subscribeOn(Schedulers.newThread())
  .delay(50, TimeUnit.MILLISECONDS)
  .observeOn(Schedulers.newThread())
  .subscribe(item -> {
    textView.setText(item); // after the delay you will get a CalledFromWrongThreadException
  });

而且这与RxJava无关。创建一个立即更新视图的线程显示相同的行为:

new Thread(new Runnable() {
  @Override
  public void run() {
    textView.setText("foo"); // no CalledFromWrongThreadException
  }
}).start();

看起来这个问题可以追溯到 ViewRootImpl checkThread(),在这种情况下没有被调用。如需进一步了解,请点击以下链接。

尽管如此,对视图的任何更改都应该在主线程中发生。你所展示的场景似乎是一个“幸运”的副作用。

文档