【问题标题】:Retrofit get the last request of multiple requests改造获取多个请求的最后一个请求
【发布时间】:2018-02-16 03:45:48
【问题描述】:

我有一个包含项目的回收站视图。当我单击一个项目时,我进行 api 调用以获取一些数据以将其附加到另一个回收器视图中,问题是当用户在回收器中的项目中单击多次时,它会发出许多 api 请求并返回最后一个,我只关心最后点击的项目请求,我想取消其余的请求并忽略它们我尝试使用计时器但它失败了

这是我当前的代码

 @Override
    public void onSelectedSourceClick(SelectedSource selectedSource, int position) {
        newsAdapter.clearNewsList();

        okHttpClient.dispatcher().cancelAll();

        if (countDownTimer != null) {
            countDownTimer.cancel();
        }
        countDownTimer = new CountDownTimer(500, 1000) {
            @Override
            public void onTick(long l) {

            }

            @Override
            public void onFinish() {
//Make the request here
                }
            }
        }.start();

    }

但是这个解决方案实际上并不起作用,所以如果任何人有解决方案或使用 RxJava 来解决它。

【问题讨论】:

  • 使用 Retrofit 2 的 Call 类来形成你的网络请求,它也允许取消它。使用数据结构(如 Stack)来保存添加的调用对象的列表,并在每次单击列表项并且必须创建新请求时检查它。如何取消请求 - futurestud.io/tutorials/retrofit-2-cancel-requests 可能也有 Rx 方式,但目前还不知道

标签: android rx-java retrofit2 okhttp3


【解决方案1】:

我正在寻找类似的东西。以下是我使用 Retrofit + RxJava 实现这一目标的方法

创建CompositeSubscription

private CompositeSubscription mSearchPlaceSubscription = new CompositeSubscription();

现在你在调用 API 和订阅新的 API 调用之前,我会这样做

mSearchPlaceSubscription.clear();

该步骤将导致取消订阅以前的请求,因此RxJavaCallAdapter 将要求 okhttp 客户端取消请求。

& 然后我通过这种方式调用API:

mSearchPlaceSubscription.add(mSearchPlacesHelper.searchPlaces(query)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<Prediction>>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(List<Prediction> predictions) {
                        setChanged();
                        notifyObservers(predictions);
                    }
                }));

这里

mSearchPlacesHelper.searchPlaces(query) 返回 Observable 到我 subscribe(返回 Subscription)。我在接受订阅对象的
mSearchPlaceSubscription.add() 内完成所有这些代码。

所以我的最终 API 调用如下所示:

mSearchPlaceSubscription.clear();
mSearchPlaceSubscription.add(mSearchPlacesHelper.searchPlaces(query)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<Prediction>>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(List<Prediction> predictions) {

                    }
                }));

希望这会有所帮助:)

【讨论】:

  • 我使用实时数据工厂返回实时数据对象而不是调用,因此我无法从中返回 obseravble
  • 对不起,我没有得到实时数据对象。你的意思是来自架构组件的 LiveData?
  • 是的,我使用自定义工厂来获取 LiveData 对象而不是调用对象
  • 我还没有使用过 LiveData,但您可以尝试类似的方法。全局存储您在 observe() 中传递的 LiveData 对象和 Observer,在再次调用 liveData.observe(myObserver) 之前,您应该执行 liveData.removeObserver(myObserver)。 & 然后重新初始化 myObserver = new Observer() & 然后将其传递给 liveData.observe(myObserver),
  • 观察者是它自己的活动 LifeCycleOwner
【解决方案2】:

您可以通过在发出新请求时取消所有待处理的请求来做到这一点。 就像如果你按下了两个项目,那么当你发出第二个请求时,使用这段代码取消所有待处理的请求。

client.dispatcher().cancelAll()

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 2018-02-24
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    相关资源
    最近更新 更多