Я использую Square Retrofit Client для выполнения коротких запросов json от приложения Android. Есть ли способ отменить запрос? Если да, то как?
Используя Square Retrofit Client, можно ли отменить запрос на выполнение? Если да, то как?
Ответ 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
Лучшая стратегия будет отменять выполнение обратного вызова
Ответ 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
Возможно, я немного опоздал, но я нашел решение. Я не смог предотвратить выполнение запроса, но если вы удовлетворены выполняемым запросом и ничего не делаете, вы можете проверить этот вопрос и ответ, оба сделаны мной.