RxJava io.reactivex.exceptions.OnErrorNotImplementedException:必须从片段主机的主线程调用

时间:2018-09-23 02:20:34

标签: rx-java2 rx-android

我对RxJava中的线程处理有些困惑。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = (Button) findViewById(R.id.btn);
    clickObservable = RxView.clicks(button);
    vpPager = findViewById(R.id.vpPager);
    adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
    vpPager.setAdapter(adapterViewPager);

    //debouncebale button.
    disposable = clickObservable
            .debounce(2000, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Object>() {
                @Override
                public void accept(Object o) throws Exception {
                    //This prints main thread.
                    Log.d(TAG, " o " + o + " thread " + Thread.currentThread().getName());
                    vpPager.setCurrentItem(vpPager.getCurrentItem() + 1, true);
                }
            });

    pageChangedObservable = RxViewPager.pageSelections(vpPager);
    pageChangedObservable
            .observeOn(AndroidSchedulers.mainThread())
            .delay(2000, TimeUnit.MILLISECONDS)
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(final Integer integer) throws Exception {
                    //This prints Thread RxComputationThreadPool-1
                    Log.d(TAG, "Thread " + Thread.currentThread().getName());
                    vpPager.setCurrentItem(integer  + 1, true);
                }
            });



}

第一个Log语句显示主线程,第二个Log语句显示RxComputationThreadPool-1。我不知道为什么。

2 个答案:

答案 0 :(得分:0)

请注意,某些运算符在指定的默认Scheduler上进行操作,尤其是与时间偏移有关的运算符(在这种情况下,例如delay)。否则,如果未指定Scheduler,它们将在生成下一个发射之前等待主线程。

如果您选中docs,则会发现delay默认在计算Scheduler上运行。

对于具有默认Scheduler的那些运算符,通常还有一个重载的变体,允许您指定所需的Scheduler

答案 1 :(得分:0)

实际上,如果您不提供Scheduler,则delay()默认情况下会使用Schedulers.computation()。

在第二种情况下,您应该使用

.delay(1,TimeUnit.SECONDS,AndroidSchedulers.mainThread())

如果要在主线程中观察结果。或移动

.observeOn(AndroidSchedulers.mainThread())

.delay()之后;

当您转到.delay()方法的定义时,可以找到它。

/ **      *返回一个Observable,它发出源ObservableSource发出的项,该项随时间向前移动      *指定的延迟。来自源ObservableSource的错误通知不会延迟。      *

计划程序:
     *默认情况下,此版本的{@code delay}在{@code Calculation} {@link Scheduler}上运行 希望我回答你的问题。