【问题标题】:Retrofit 2/OkHttp: Cancel all running requestsRetrofit 2/OkHttp:取消所有正在运行的请求
【发布时间】:2016-03-25 21:19:09
【问题描述】:

我正在使用带有 OkHttp 2.7.0 的 Retrofit 2-beta2。

为了从 Retrofit 获取 OkHttpClient 对象,我使用 Retrofit .client() 方法并取消它所有正在运行的请求,我称之为 cancel(Object tag) 方法,但请求仍在运行,我得到了响应。

即使是客户端的DispatchergetQueuedCallCount()getRunningCallCount() 在调用cancel() 后也返回0。

我还需要做些什么才能使其正常工作吗?或者它可能是 OkHttp 中的一个错误?

作为一种解决方法,我在客户的ExecutorService 上调用shutdownNow(),但我更喜欢更简洁的解决方案。

【问题讨论】:

  • 在浏览了源代码之后,我现在明白为什么这不起作用了。我正在使用拦截器在Request 上设置标签,因此创建了一个新的Request 对象。 OkHttpClient.cancel(Object tag) 什么都不做,因为原始的 Request(在其上调用 cancel(),因为它存在于 Dispatcher 的请求队列中)仍然没有标签集。似乎 Retrofit 没有公开任何方法或接口来在原始 Request 对象上设置标签。

标签: java android retrofit okhttp


【解决方案1】:

更新: 现在在 OkHttp 3 中使用 Dispatcher 更容易实现,它有一个 cancelAll() 方法。调度程序从OkHttpClient.dispatcher()返回。

旧解决方案: 做到这一点的唯一方法(我能找到)是创建一个 OkHttpClient 的子类并将其与 Retrofit 一起使用。

class OkHttpClientExt extends OkHttpClient {
    static final Object TAG_CALL = new Object();

    @Override
    public Call newCall(Request request) {
        Request.Builder requestBuilder = request.newBuilder();
        requestBuilder.tag(TAG_CALL);
        return super.newCall(requestBuilder.build());
    }
}

以下行取消所有带有标签TAG_CALL 的请求。由于上面的类对所有请求都设置了TAG_CALL,所以所有请求都被取消了。

retrofit.client().cancel(OkHttpClientExt.TAG_CALL);

【讨论】:

  • 您可以添加一个 RequestInterceptor 并为每个请求添加标签,而不是扩展 OkHttpClient。
  • @Matthew 是的,使用Interceptor 设置标签也可以。但是,使用 OkHttp 3,这不再需要,因为 Dispatcher 提供了 cancelAll() 方法,该方法取消所有请求,而与标签无关。
  • 不知道 Dispatcher 类,非常有帮助!
  • 我无法从 OkHttpClient.Builder 或 Retrofit 实例访问 dispatcher() 方法和 cancelAll() 方法。请给我一个完整的例子。
  • @Madhan 您可以从OkHttpClient.Builder.build() 返回的OkHttpClient 实例访问dispatcher()square.github.io/okhttp/3.x/okhttp/okhttp3/…square.github.io/okhttp/3.x/okhttp/okhttp3/…
猜你喜欢
  • 2020-08-29
  • 2021-01-18
  • 2017-09-03
  • 2016-12-08
  • 2017-02-13
  • 2015-12-12
  • 2014-08-25
  • 1970-01-01
  • 2016-05-24
相关资源
最近更新 更多