Выполнять запросы с помощью Retrofit внутри пользовательского Runnable
Я мигрирую из Volley
к пользовательской реализации с использованием Retrofit
, но я пытаюсь добавить в мою реализацию некоторые из Volley
функции, которые мне понравились, например
RequestQueue.cancel(строковый тег)
Если Request
имеет запрошенный тег, затем он отменяется установкой boolean
значение, mCanceled
, чтобы правда. run
Метод проверяет это значение и возвращает значение true. Чтобы иметь возможность воспроизвести это с Retrofit
Я должен быть в состоянии использовать свой собственный класс реализации Runnable
вместо по умолчанию, где у меня есть mTag
и mCanceled
поле. Более того, Volley
также был в состоянии установить такой флаг внутри активного Thread
и немедленно остановить их. мой cancelAll
метод, который я уже реализовал, просто перетаскивает очередь в другую очередь, но не может получить доступ к активным потокам. Можно ли добиться таких же результатов с Retrofit
а также ThreadPoolExecutor
?
2 ответа
Я думаю, что нашел лучшее решение: вместо того, чтобы блокировать Runnable
из запросов, я блокирую Callback
выполнение.
Я продлил Callback
интерфейс:
public interface CustomCallbackInterface<T> extends Callback<T> {
public String getTag();
public String setTag(String tag);
public void cancel();
public boolean isCanceled();
}
так что каждый Callback
имеет тег и флаг отмены. Тогда success
Метод начинается с:
public class CustomCallback<ConvertedData> implements CustomCallbackInterface<ConvertedData>{
//failure...
@Override
public void success(ConvertedData cd, Response response) {
if(isCanceled()) return;
// ....
}
}
Каждый раз, когда я делаю новый запрос, я сохраняю CustomCallback
внутри List
отмена просто повторяет список и звонки cancel()
на предметы с таким же тегом.
Я реализовал простой в использовании класс на основе ответа Vektor88
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);