Reputation: 3
I'm new to Android development and am currently trying to make a simple MVC app that works with Rest API. API calls are made without using Retrofit, although this is not so important. The main catch is that using Observable with debounce and SwitchMap I still get too many API calls (and the extra ones should be discarded). The function is called when text is entered (EditText Listener with TextWatcher). And when administered continuously without delay word, every symbol processed by the server and should only be administered when not within 600 milliseconds. Please help me.
public Observable<String> getObservable(final String s){
return Observable
.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext(model.translateText(s));
}
});
}
public Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
mainView.hideProgress();
mainView.showResult(s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
public void onEditTextChange(String textForTranslate){
mainView.showProgress();
getObservable(textForTranslate)
.debounce(600,TimeUnit.MILLISECONDS)
.switchMap(new Function<String, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(String s) throws Exception {
return Observable.just(s);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}
Upvotes: 0
Views: 1074
Reputation: 439
You are creating a new observable every time a character is typed. So multiple observers are created with each having separate debounce (time throttle) and switch but they are not reused. Instead you create a new observable whenever text changes and start rx chain on it.
You need to create a single PublishSubject
private final PublishSubject<String> querySubject = PublishSubject.create();
that emits entered text/query whenever text is changed. Use it in your callback:
public void onEditTextChange(String textForTranslate) {
querySubject.onNext(textForTranslate);
}
And in your main function, subscribe to observable:
querySubject
.debounce(600, TimeUnit.MILLISECONDS)
.distinctUntilChanged()
.switchMap(new Function<String, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(String s) throws Exception {
// perform api call or any other operation here
return Observable.just(s);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
Debounce
operator emits single item only after given time (600 ms) has passed. It ignores items if current item is being processed and given time has not passed.
distinctUntilChanged
helps in reducing processing of same query.
Upvotes: 2