Используя Square Retrofit Client, можно ли отменить запрос на выполнение? Если да, то как?
Я использую Square Retrofit Client для выполнения коротких запросов json от приложения Android. Есть ли способ отменить запрос? Если да, то как?
Ответы
Ответ 1
Для отмены запроса async Retrofit вы можете добиться этого, отключив ExecutorService, который выполняет асинхронный запрос.
Например, у меня был этот код для создания 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()));
и имел этот метод для решительного отказа от запросов:
public void stopAll(){
List<Runnable> pendingAndOngoing = mExecutorService.shutdownNow();
// probably await for termination.
}
В качестве альтернативы вы можете использовать ExecutorCompletionService
и либо poll(timeout, TimeUnit.MILISECONDS)
, либо take()
все текущие задачи. Это предотвратит закрытие пула потоков, как это было бы с shutdownNow()
, и вы можете повторно использовать ExecutorService
Надеюсь, что это поможет кому-то.
Изменить: по состоянию на OkHttp 2 RC1 changelog выполняется .cancel(Object tag)
. Мы должны ожидать такую же особенность в предстоящей Retrofit:
Вы можете использовать фактический объект Request
для его отмены
okClient.cancel(request);
или если вы указали тег на Request.Builder
, вы должны использовать
okClient.cancel(request.tag());
Все текущие, выполненные или ожидающие запросы помещаются в очередь внутри Dispatcher
, okClient.getDispatcher()
. Вы также можете вызвать метод отмены на этом объекте. Метод Cancel уведомит OkHttp Engine
, чтобы убить соединение с хостом, если оно уже установлено.
Изменить 2. В Retrofit 2 есть полнофункциональные запросы на отмену.
Ответ 2
Оберните обратный вызов в объекте делегата, который реализует обратный вызов как Что ж. Вызовите какой-то метод, чтобы очистить делегата и просто его no-op, когда он получает ответ.
Посмотрите на следующее обсуждение
https://plus.google.com/107765816683139331166/posts/CBUQgzWzQjS
Лучшая стратегия будет отменять выполнение обратного вызова
fooobar.com/questions/812900/...
Ответ 3
Я реализовал отмененный класс обратного вызова на основе ответа fooobar.com/questions/812900/...
public abstract class CancelableCallback<T> implements Callback<T> {
private static List<CancelableCallback> mList = new ArrayList<>();
private boolean isCanceled = false;
private Object mTag = null;
public static void cancelAll() {
Iterator<CancelableCallback> iterator = mList.iterator();
while (iterator.hasNext()){
iterator.next().isCanceled = true;
iterator.remove();
}
}
public static void cancel(Object tag) {
if (tag != null) {
Iterator<CancelableCallback> iterator = mList.iterator();
CancelableCallback item;
while (iterator.hasNext()) {
item = iterator.next();
if (tag.equals(item.mTag)) {
item.isCanceled = true;
iterator.remove();
}
}
}
}
public CancelableCallback() {
mList.add(this);
}
public CancelableCallback(Object tag) {
mTag = tag;
mList.add(this);
}
public void cancel() {
isCanceled = true;
mList.remove(this);
}
@Override
public final void success(T t, Response response) {
if (!isCanceled)
onSuccess(t, response);
mList.remove(this);
}
@Override
public final void failure(RetrofitError error) {
if (!isCanceled)
onFailure(error);
mList.remove(this);
}
public abstract void onSuccess(T t, Response response);
public abstract void onFailure(RetrofitError error);
}
Пример использования
rest.request(..., new CancelableCallback<MyResponse>(TAG) {
@Override
public void onSuccess(MyResponse myResponse, Response response) {
...
}
@Override
public void onFailure(RetrofitError error) {
...
}
});
// if u need to cancel all
CancelableCallback.cancelAll();
// or cancel by tag
CancelableCallback.cancel(TAG);
Ответ 4
Теперь в последней версии Retrofit V 2.0.0.beta2 есть простой способ. Может также выполнить повторную попытку.
Посмотрите здесь Как отменить текущий запрос в модификации, когда retrofit.client.UrlConnectionClient используется как клиент?
Ответ 5
Это для модификации 2.0, метод call.cancel(), который отменяет вызов в полете. ниже это определение документа для него.
retrofit2.Call
public abstract void cancel()
Отмените этот вызов. Будет предпринята попытка отменить звонки в полете, и если вызов еще не был выполнен, он никогда не будет.
Ответ 6
Согласно Retrofit 2.0 beta 3 changelog по ссылке https://github.com/square/retrofit/releases/tag/parent-2.0.0-beta3
Новый метод: isCanceled() возвращает ли вызов отменен. Используйте это в onFailure, чтобы определить, был ли обратный вызов вызван с отменой или фактическим отказом транспорта.
Это должно облегчить работу.
Ответ 7
Возможно, я немного опоздал, но я нашел решение.
Я не смог предотвратить выполнение запроса, но если вы удовлетворены выполняемым запросом и ничего не делаете, вы можете проверить этот вопрос и ответ, оба сделаны мной.