结合两个不同的可观察量

时间:2016-06-28 05:14:04

标签: android rx-java rx-android

拥有以下代码段:

 Log.d("#######", Thread.currentThread().getName());
    RxSearchView.queryTextChangeEvents(searchView)
            .debounce(400, TimeUnit.MILLISECONDS,Schedulers.newThread())
            .flatMap(new Func1<SearchViewQueryTextEvent, Observable<GifsData>>() {
                @Override
                public Observable<GifsData> call(SearchViewQueryTextEvent txtChangeEvt) {
                    return RestWebClient.get().getSearchedGifs(txtChangeEvt.queryText().toString(),"dcJmzC");
                }
            })
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<GifsData>() {
                @Override
                public void onCompleted() {
                    Log.d("#######","onCompleted searchGifs");
                }

                @Override
                public void onError(Throwable e) {
                    Log.d("#######",e.toString());
                }

                @Override
                public void onNext(GifsData gifsData) {
                   mainFragmentPresenterInterface.displaySearchedGifsList(gifsData);
                }
            });
}

无论我尝试什么,我都会收到以下错误:

java.lang.IllegalStateException: Must be called from the main thread. Was: Thread[RxNewThreadScheduler-2,5,main]

可能已经花了将近一个小时的时间......没能找出问题所在。甚至尝试将我的代码段与以下链接匹配:

Combine RxTextView Observable and Retrofit Observable

没有运气。有人能指出这里有什么问题吗?

感谢。

2 个答案:

答案 0 :(得分:2)

错误原因:您在后台线程上订阅结果,并且您正在后台线程上访问流中的View。在这里,我在后台调度程序上调用了RestWebClient.get().getSearchedGifs(txtChangeEvt.queryText().toString(),"dcJmzC").subscribeOn(Schedulers.newThread());。请尝试这个适用于你:

RxSearchView.queryTextChangeEvents(mSearchView)
            .debounce(400, TimeUnit.MILLISECONDS)
            .flatMap(new Func1<SearchViewQueryTextEvent, Observable<String>>() {
                @Override
                public Observable<String> call(SearchViewQueryTextEvent txtChangeEvt) {
                    return Observable.just(txtChangeEvt.queryText().toString()).subscribeOn(AndroidSchedulers.mainThread());
                }
            })
            .flatMap(new Func1<GifsData, Observable<String>>() {
                @Override
                public Observable<GifsData> call(String txtChangeEvt) {
                    return RestWebClient.get().getSearchedGifs(txtChangeEvt,"dcJmzC").subscribeOn(Schedulers.newThread());
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<GifsData>() {
                @Override
                public void onCompleted() {
                    Log.d("#######","onCompleted searchGifs");
                }

                @Override
                public void onError(Throwable e) {
                    Log.d("#######",e.toString());
                }

                @Override
                public void onNext(GifsData gifsData) {
                    Log.d("#######", gifsData);
                }
            });

如果有帮助请告诉我

答案 1 :(得分:0)

默认情况下,运算符debounce使用computation调度程序,您需要将其更改为主线程(因为您只在main上使用UI)。

接下来要安排在io调度程序上执行网络请求。 (我们现在只使用一个subscribeOn

再次观察主线程上与UI反应的结果。

RxSearchView.queryTextChangeEvents(searchView)
  .debounce(400, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
  .flatMap(new Func1<SearchViewQueryTextEvent, Observable<GifsData>>() {
    @Override
    public Observable<GifsData> call(SearchViewQueryTextEvent txtChangeEvt) {
      return RestWebClient.get()
        .getSearchedGifs(txtChangeEvt.queryText().toString(),"dcJmzC")
        .subscribeOn(Schedulers.io());
    }
  })
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Observer<GifsData>() {
    @Override
    public void onCompleted() {
      Log.d("#######","onCompleted searchGifs");
    }

    @Override
    public void onError(Throwable e) {
      Log.d("#######",e.toString());
    }

    @Override
    public void onNext(GifsData gifsData) {
      mainFragmentPresenterInterface.displaySearchedGifsList(gifsData);
    }
});