如何取消Retrofit2 Rxjava2

时间:2018-09-05 08:30:56

标签: android retrofit2 rx-java2

我向youtube api搜索创建了一个请求。 发送请求后,必须取消之前的请求,并且不对缓存进行任何更新。

我使用CompositeDisposable添加了每个Disposable并在创建新请求时将其清除。

但是,正如我注意到先前的请求没有取消一样,缓存仍在更新。

   disposable.clear();
   disposable.add(Network.search(nextPageToken, (isSearchingOnline() ? mFilterText : ""), item.topicId, listener));


public static Disposable search(String nextPageToken, String query, String topicId, String publishedAfter, OnYoutubeSearchListener listener) {
        YParams yParam = new YParams(50, Constants.YOUTUBE_DEVERLOPE_KEY, "snippet", "video", nextPageToken, "10", query, publishedAfter, topicId);
        if (cacheData.containsKey(yParam)) {
            if (listener != null) {
                for (Map.Entry<YParams, List<VideoBean>> entry : cacheData.entrySet()) {
                    YParams key = entry.getKey();
                    List<VideoBean> value = entry.getValue();
                    if (key.equals(yParam)) {
                        listener.onReturnPageToken(key.getNextPageToken());
                        listener.onSuccess(value);
                        break;
                    }
                }
            }
            return new CompositeDisposable();
        }
        return Network.getYoutubeApi().search(50, Constants.YOUTUBE_DEVERLOPE_KEY, "snippet", "video", nextPageToken, "10", "", publishedAfter, "")
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .flatMap((Function<Videos, ObservableSource<Videos>>) videos -> {
                    if (videos.items.size() > 0) {
                        StringBuilder builder = new StringBuilder();
                        for (Videos.Item i : videos.items) {
                            builder.append(i.id.videoId);
                            builder.append(",");
                        }
                        yParam.setNextPageToken(videos.nextPageToken);
                        if (listener != null) {
                            listener.onReturnPageToken(videos.nextPageToken);
                        }
                        return Network.getYoutubeApi().getVideosDetail(Constants.YOUTUBE_DEVERLOPE_KEY, builder.substring(0, builder.length() - 1), "snippet,contentDetails,statistics");
                    }
                    return Observable.fromArray(Videos.EMPTY_VIDEOS);
                })
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Function<Videos, List<VideoBean>>() {
                    @Override
                    public List<VideoBean> apply(Videos videos) {
                        List<VideoBean> list = new ArrayList();
                        for (Videos.Item bean : videos.items) {
                            list.add(new VideoBean(bean.id.videoId, bean.snippet.title, bean.snippet.description, bean.snippet.thumbnails._default.url, bean.snippet.channelTitle, bean.contentDetails.duration, bean.snippet.publishedAt, 0));
                        }
                        return list;
                    }
                })
                .subscribe(items -> {
                    if (items != null && items.size() > 0) {
                        cacheData.put(yParam, items);
                    }
                    if (listener != null) {
                        listener.onSuccess(items);
                    }
                }, throwable -> {
                    if (listener != null) {
                        listener.onFailed(throwable);
                    }
                });
    }

2 个答案:

答案 0 :(得分:1)

  

如何在Android中取消Retrofit2 Rxjava2?

您必须保留对Disposable对象的引用并在其上调用dispose()

答案 1 :(得分:-1)

我认为主要问题是您使用clear()方法而不是dispose()。如果打开它的源代码,将会看到clear()不会更改侦听器的处置状态。这个方法没有设置dispose = true。也许正因为如此,您的回调在搜索请求完成时触发。

您还可以了解有关debounce()运算符的更多信息。通常,它与即时搜索配合使用,以防止用户快速打印查询并在每次输入更改时启动搜索时避免不必要的请求。 https://www.androidhive.info/RxJava/rxjava-operators-buffer-debounce/

如果要使用dispose()方法,则还必须在处理后重新初始化CompositeDisposable。

CompositeDisposable d = new CompositeDisposable();
d.add(executeSomething());

// Clear requests
d.dispose();
d = new CompositeDisposable();