Выполнять запросы с помощью 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);
Другие вопросы по тегам