Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Square's Retrofit Client, is it possible to cancel an in progress request? If so how?

I'm using Square's Retrofit Client to make short-lived json requests from an Android App. Is there a way to cancel a request? If so, how?

like image 376
Alfie Hanssen Avatar asked Aug 08 '13 16:08

Alfie Hanssen


People also ask

What is a retrofit client?

Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp. See this guide to understand how OkHttp works.

What is the use of retrofit in Android?

Retrofit is type-safe REST client for Android and Java which aims to make it easier to consume RESTful web services. We'll not go into the details of Retrofit 1. x versions and jump onto Retrofit 2 directly which has a lot of new features and a changed internal API compared to the previous versions.


1 Answers

For canceling async Retrofit request, you can achieve it by shutting down the ExecutorService that performs the async request.

For example I had this code to build the RestAdapter:

Builder restAdapter = new RestAdapter.Builder();
restAdapter.setEndpoint(BASE_URL);
restAdapter.setClient(okClient);
restAdapter.setErrorHandler(mErrorHandler);
mExecutorService = Executors.newCachedThreadPool();
restAdapter.setExecutors(mExecutor, new MainThreadExecutor());
restAdapter.setConverter(new GsonConverter(gb.create()));

and had this method for forcefully abandoning the requests:

public void stopAll(){
   List<Runnable> pendingAndOngoing = mExecutorService.shutdownNow();
   // probably await for termination.
}

Alternatively you could make use of ExecutorCompletionService and either poll(timeout, TimeUnit.MILISECONDS) or take() all ongoing tasks. This will prevent thread pool not being shut down, as it would do with shutdownNow() and so you could reuse your ExecutorService

Hope it would be of help for someone.

Edit: As of OkHttp 2 RC1 changelog performing a .cancel(Object tag) is possible. We should expect the same feature in upcoming Retrofit:

You can use actual Request object to cancel it

okClient.cancel(request);

or if you have supplied tag to Request.Builder you have to use

okClient.cancel(request.tag());

All ongoing, executed or pending requests are queued inside Dispatcher, okClient.getDispatcher(). You can call cancel method on this object too. Cancel method will notify OkHttp Engine to kill the connection to the host, if already established.

Edit 2: Retrofit 2 has fully featured canceling requests.

like image 173
Nikola Despotoski Avatar answered Sep 17 '22 17:09

Nikola Despotoski