2015-12-19 21 views
7

Tôi đang sử dụng trang bị thêm 2-beta2 với OkHttp 2.7.0.Trang bị thêm 2/OkHttp: Hủy tất cả các yêu cầu đang chạy

Để nhận đối tượng OkHttpClient từ trang bị thêm Tôi đang sử dụng phương pháp Retrofit .client() và hủy tất cả yêu cầu đang chạy, tôi gọi phương thức đó là cancel(Object tag) nhưng yêu cầu vẫn tiếp tục chạy và tôi nhận được phản hồi.

Ngay cả số getQueuedCallCount()getRunningCallCount() trả lại 0 sau khi gọi hủy().

Có điều gì khác mà tôi cần thực hiện để hoạt động không? Hoặc nó có thể là một lỗi trong OkHttp?

Giải pháp thay thế, tôi gọi số shutdownNow() trên máy khách của ExecutorService nhưng tôi muốn có giải pháp sạch hơn.

+0

Sau khi xem qua mã nguồn, bây giờ tôi hiểu tại sao điều này không hiệu quả. Tôi đang thiết lập thẻ trên 'Request' bằng cách sử dụng một interceptor do đó tạo một đối tượng' Request' mới. 'OkHttpClient.cancel (Thẻ đối tượng)' không làm gì kể từ gốc 'Yêu cầu' (trên đó' hủy() 'được gọi vì nó hiện diện trong hàng đợi yêu cầu' Dispatcher') vẫn không có thẻ. Có vẻ như Retrofit không trưng ra bất kỳ phương thức hoặc giao diện nào để thiết lập một thẻ trên đối tượng 'Request' ban đầu. –

Trả lời

15

UPDATE: này bây giờ là dễ dàng hơn nhiều để đạt được trong OkHttp 3 bằng cách sử dụng Dispatcher trong đó có một phương pháp cancelAll(). Điều phối viên được trả lại từ OkHttpClient.dispatcher().

Giải pháp cũ: Cách duy nhất để thực hiện việc này (mà tôi có thể tìm thấy) là tạo một lớp con OkHttpClient và sử dụng trang này với 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()); 
    } 
} 

Dòng sau hủy tất cả yêu cầu với thẻ TAG_CALL. Vì lớp ở trên đặt số TAG_CALL cho tất cả các yêu cầu nên tất cả các yêu cầu đều bị hủy.

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

Thay vì mở rộng OkHttpClient, bạn chỉ có thể thêm một RequestInterceptor và thêm thẻ của bạn cho mỗi yêu cầu. – Matthew

+5

@Matthew Có, thiết lập thẻ với một 'Interceptor' cũng sẽ hoạt động tốt. Tuy nhiên, với OkHttp 3, điều này không còn cần thiết vì 'Dispatcher' cung cấp phương thức' cancelAll() 'hủy bỏ tất cả các yêu cầu không phụ thuộc vào các thẻ. –

+2

Không nhận thức được lớp 'Dispatcher', rất hữu ích! – Matthew

Các vấn đề liên quan