本文介绍了为什么 onNext() 正在更新 textview,而 observeOn(Schedulars.io()) 在不同的线程上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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?

onNext() supposed to run on separate thread, but how is it updating textview, which is on main thread?

推荐答案

似乎在视图生命周期的最初阶段,您可以在很短的时间内从主线程更改视图.

It seems that at the very beginning of the lifetime of a view, there is a very short timespan where you are able to change the view off the main thread.

当您直接在 onCreate() 中从主线程启动一个线程时,该线程几乎立即返回结果(因为没有实际工作要做),您将不会得到 CalledFromWrongThreadException 调整视图时.

As you started a thread off the main thread, directly in onCreate(), and this thread almost instantly returns a result (as there is no real work to do) you will not get a CalledFromWrongThreadException when you adjust the view.

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

If you put a short delay (maybe it is different on your machine) - for me, 50ms was enough - before the work in the thread / Observable starts, you will see the expected 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 无关.创建一个立即更新视图的线程显示相同的行为:

And this is not related to RxJava. Creating a Thread which updates the view immediately shows the same behavior:

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

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

Looks like this issue goes back to ViewRootImpl checkThread() which did not get called in this case. For further understanding follow the links below.

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

Despite, any change to a view should happen from the main thread. The scenario you have shown seems like a "lucky" side-effect.

文档

这篇关于为什么 onNext() 正在更新 textview,而 observeOn(Schedulars.io()) 在不同的线程上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 12:49