android - 将它与用于 android 搜索功能的 Rx-Java 一起使用时如何停止多个改造调用?

标签 android retrofit rx-java retrofit2 rx-android

我的 Android 应用程序中有搜索功能。 searchView 有回调 onSearchTextChanged(String oldQuery, String newQuery)。每次用户在搜索字段中输入任何文本时都会调用此回调函数。我在此回调中有一个 REST 调用,每次输入每个单词时都会触发该调用。这导致多次调用 REST。我想避免这种情况。我只希望一次只激活一个实例,这是最新的一个实例,并且只要键入新字母,所有其他调用都应立即取消。以下是代码详细信息。

 @Override
    public void onSearchTextChanged(String oldQuery, String newQuery) {

        floatingSearchView.showProgress();
        moviesAPI.searchQuery(newQuery)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Search>() {
                               @Override
                               public void onCompleted() {
                                   Log.d(TAG, "onCompleted() called");
                               }

                               @Override
                               public void onError(Throwable e) {
                                   Log.d(TAG, "onError() called with: e = [" + e + "]");
                               }

                               @Override
                               public void onNext(Search search) {
                                   floatingSearchView.hideProgress();
                                   floatingSearchView.swapSuggestions(search.getSearchResults());
                                   Log.d(TAG, "onNext() called with: search = [" + search + "]");
                               }
                           }

                );

    }

最佳答案

您可能希望在键入时使用去抖来延迟搜索请求(并且仅在用户停止键入 x 持续时间之后)。

此外,为了在新请求到达时取消旧请求,您可以将文本更改事件转换为事件流(手动或使用 RxBindings 之类的库),然后切换映射每个新文本事件以进行查询。 当由新的搜索文本流驱动的新请求到达时,switchMap 运算符将取消之前仍在进行的请求。

您可以找到各种使用 rxjava 为 android 实现搜索建议的示例,例如 Kaushik Gopal 的示例:instantauto-searching-text-listeners-using-subjects--debounce

代码示例,此示例使用RxBinding用于轻松获取 textChanages 事件作为 Observable 流的库。

RxTextView.textChangeEvents(tv)
                .debounce(300, TimeUnit.MILLISECONDS)
                .switchMap(new Func1<TextViewTextChangeEvent, Observable<SearchResult>>() {
                    @Override
                    public Observable<SearchResult> call(
                            TextViewTextChangeEvent textViewTextChangeEvent) {
                        return moviesAPI.searchQuery(textViewTextChangeEvent.text().toString())
                                .subscribeOn(Schedulers.io());
                    }
                })
                .subscribe(new Subscriber<SearchResult>() {
                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "onCompleted() called");
                    }

                    @Override
                    public void onError(Throwable e) {
                        floatingSearchView.hideProgress();
                        Log.d(TAG, "onError() called with: e = [" + e + "]");
                    }

                    @Override
                    public void onNext(SearchResult search) {
                        floatingSearchView.hideProgress();
                        floatingSearchView.swapSuggestions(search.getSearchResults());
                        Log.d(TAG, "onNext() called with: search = [" + search + "]");
                    }
                });

关于android - 将它与用于 android 搜索功能的 Rx-Java 一起使用时如何停止多个改造调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42049372/

相关文章:

java - 将 listView 数据从一个 Activity 发送到另一 Activity

javascript - Android 关于 :debug fixes JS 的错误

Android SharedPreferences 备份不工作

android - 无法解决 : com. google.firebase :firebase-core:11. 2.0

java - 如何从自定义 ArrayList 中获取特定条目?

android - PUT 上传文件到 AWS S3 预签名 url Retrofit2 Android

android - 我应该把我的 retrofit 电话和 Android 服务类放在里面吗?

java - 适配 RxJava 1.1.5 到 Reactor Core 3.1.0.M3

android - 如何使用 RxAndroidBle 结合服务发现和读取特征

rx-java - 多个可观察量链接在一起以完成