Reputation: 9152
Have the following snippet:
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);
}
});
}
No matter what i try i keep getting the following error:
java.lang.IllegalStateException: Must be called from the main thread. Was: Thread[RxNewThreadScheduler-2,5,main]
Probably have spend close to an hour on this..Haven't been able to figure out what is the issue. Even tried matching my snippet to the following link:
Combine RxTextView Observable and Retrofit Observable
No luck. Can someone point out what is wrong here?
Thanks.
Upvotes: 1
Views: 161
Reputation: 1446
Operator debounce
by default uses computation
scheduler, you need to change it to main thread (because you work with UI only on main).
Next thing is to schedule network request to be executed on io
scheduler.
(we are using only one subscribeOn
now).
And again observing results on main thread to inreact with 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);
}
});
Upvotes: 0
Reputation: 2446
Reason of error: You are subscribing result on background thread and you are accessing View in stream on background thread. Here I have invoked RestWebClient.get().getSearchedGifs(txtChangeEvt.queryText().toString(),"dcJmzC").subscribeOn(Schedulers.newThread());
on background scheduler .Please try this it will work for you:
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);
}
});
Let me know if it helps
Upvotes: 2