当我使用doOnSubscribe()时为什么要调用onNext()两次

时间:2017-03-11 18:07:45

标签: android rx-java

就像这个样本

  Observable.fromCallable(() -> okHttp.getDataFromNet(page))
            .subscribeOn(Schedulers.io())
            .doOnSubscribe(()->{adapter.loadmore})
            .subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<String>() {
                @Override
                public void onCompleted() {
                    adapter.stopLoad();
                }

                @Override
                public void onError(Throwable throwable) {

                }

                @Override
                public void onNext(String s) {
                  Log.e("fail","fail");
                  adapter.add();
                }
            });

我发现onNext在这种情况下会被调用两次。如果我在Log.e()中添加{ onCompleted(),它也会调用两次。我的代码出了什么问题。如果在Subscriber中调用一个方法,那么我添加doOnSubscribe()它将被调用两次。< / p>

//progressbarAdapter extends Recyclerview.Adapter
static final int LOADING_TYPE = -1;
private boolean isLoading = false;
 public void loadingMore(){
    isLoading = true;
    notifyItemInserted(getItemCount());
    // size = index +1
}
public void loadingEnd(){
    notifyItemRemoved(getItemCount());
    isLoading = false;
}

@Override
public int getItemCount() {
    return getDataCount() + (isLoading ? 1: 0);
}

@Override
public int getItemViewType(int position) {
    if (position == getDataCount() && !isError){
        return LOADING_TYPE;
    }else {
        return getExtItemViewType(position);
    }
}

真正的原因

当adapter.notify它将触发滚动方法,因此它将被调用两次。对不起,我问了一个不好的问题。

1 个答案:

答案 0 :(得分:1)

请看看如何使用observeOn和subscribeOn。对于一个可观察的只能有一个subscribeOn。如果你使用多个,最后一个获胜。使用observeOn在管道和subscribeOn之间切换线程,以指定将创建observable的线程。

我转换了您给定的代码,以便在测试中使用它。我只得到一个onNext-call。

问题:被叫两次。 这可能是因为flatMap中的其他地方错误地使用了observable,或者是对observable的多次订阅。请提供更多背景信息。

Testenvironment:IntelliJ Idea 2017 EAP,io.reactivex:rxjava:1.2.1

@Test
public void name() throws Exception {
    Observable<String> doOnSub = Observable.just("1")
            .subscribeOn(Schedulers.io())
            .doOnSubscribe(() -> {
                System.out.println("doOnSub");
            })
            .subscribeOn(Schedulers.computation())
            .observeOn(Schedulers.computation());

    TestSubscriber<String> objectTestSubscriber = TestSubscriber.create();

    doOnSub.subscribe(objectTestSubscriber);


    objectTestSubscriber.awaitTerminalEvent();
    objectTestSubscriber.assertValues("1");
}