问题
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() supposed to run on separate thread, but how is it updating textview, which is on main thread?
回答1:
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.
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.
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
});
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();
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.
Documentation
- Android UI Not Crashing When Modifying View off UI Thread
- Why is there no CalledFromWrongThreadException when a new thread operates UI immediately?
回答2:
If you are using 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.
回答3:
observeOn is an async operation and after its processed , the result to pushed to onNext whixh is intended to run on the UI thread. They are changing the threading for us.Thats an advantage isnt? Its the feature of RxJava
来源:https://stackoverflow.com/questions/65502555/why-onnext-is-updating-textview-though-observeonschedulars-io-on-a-differ