2015-12-19 119 views
7

我使用的是OkHttp 2.7.0的Retrofit 2-beta2。Retrofit 2/OkHttp:取消所有正在运行的请求

为了得到改造的OkHttpClient对象我使用的Retrofit .client()方法,并取消所有它的运行要求,我打电话是cancel(Object tag)方法,但请求仍保持运行,我得到回应。

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

有什么我需要做的这个工作?或者它可能是OkHttp中的一个错误?

作为解决方法,我打电话shutdownNow()在客户的ExecutorService,但我更喜欢更清洁的解决方案。

+0

通过源代码后,我现在明白为什么这不起作用。我使用拦截器在'Request'上设置标签,因此创建一个新的'Request'对象。 'OkHttpClient.cancel(Object tag)'不会做任何事情,因为原来的'Request'(在'Dispatcher'的请求队列中存在'cancel()'被调用)仍然没有标记集。看来Retrofit不会公开任何方法或接口在原始'Request'对象上设置标签。 –

回答

15

UPDATE:现在这是通过使用Dispatcher具有cancelAll()方法在OkHttp 3实现容易得多。调度员从OkHttpClient.dispatcher()返回。

老办法: 只有这样,才能做到这一点(我能找到),是创造的OkHttpClient一个子类,并使用与改造。

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); 
+1

而不是扩展OkHttpClient,您可以添加一个RequestInterceptor并为每个请求添加标签。 – Matthew

+5

@Matthew是的,使用'Interceptor'设置标签也可以。然而,在OkHttp 3中,由于Dispatcher提供了取消所有请求的cancelAll()方法,所以不再需要这个方法,不管标记如何。 –

+2

不知道“Dispatcher”类,非常有帮助! – Matthew