В настоящий момент я использую mRequestQueue.cancelAll(getActivity()) при методе остановки в фрагменте, но, видимо, когда я перемещаю телефон от пейзажа к портрету, он все еще возвращает данные, сделанные в запросе, но вызывает сбой, потому что держатели для дозиметра данных уже существуют. любой пример кода, как это сделать правильно?
Отменить все запросы Volley
Ответ 1
Вместо того, чтобы использовать тег для cancelAll, создайте All-Pass RequestFilter.
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
return true;
}
});
EDIT: это отменяет все запросы от всех действий/фрагментов и не работает благоприятно с жизненным циклом активности. Лучший способ справиться с этим - добавить тег String, уникальный для вашего фрагмента.
Ответ 2
Вы должны установить тег для объекта, а не для метода.
Установив тег на getActivity()
, вы попросите Volley использовать динамический вызов метода в основном потоке в качестве ссылки на запрос, который происходит в фоновом потоке.
Поэтому, когда фоновый поток пытается отменить запросы, активность уже может быть мертвой.
Вместо использования getActivity()
используйте this
или какой-либо другой объект или строку.
Это хорошая практика для любого тега, и вы также должны остерегаться утечки активности.
Решения:
Вы можете использовать текущий объект:
request.setTag(this);
или, объект статического класса
request.setTag(MyFragment.class);
или, как константа в отдельном классе:
request.setTag(CustomTags.LIST_REQUESTS);
CustomTags.LIST_REQUESTS является лучшим на мой взгляд (меньше шансов на утечку активности)
Что-то вроде этого:
public class CustomTags
{
public static final String LIST_REQUESTS="CustomTags:LIST_REQUESTS";
}
Обновление
Я только заметил, что я ошибался в пометке моих запросов в Volley (хотя решения, которые я опубликовал выше, в порядке).
Я все еще думал, что буду обновлять здесь важную вещь, о которой нужно помнить. Знаки волейбола идентичность не значение.
Таким образом, важно иметь в виду, что тег, который является просто одним и тем же строковым значением, а не тот же самый объект, не будет распознаваться как тот же tag
.
Это похоже на разницу между
String a1 = "A";
String a2 = "A";
a1 == a2; //evaluates to false
String a1 = "A";
String a2 = "A";
a1.equals(a2); // evaluates to true
Ответ 3
Я знаю, что этот ответ приходит в последнее время, но в случае, если кто-то еще сталкивается с этой проблемой:
В моей реализации тег устанавливался (и перезаписывался) в том месте, где запрос был добавлен в очередь.
Таким образом, несмотря на то, что я отменял запрос с помощью своего тега, тег в очереди запросов не был таким же (как это было ранее перезаписано), и он не был отменен.
Регистрация выполняемых запросов и печать тегов привела меня к решению:
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
Log.d("DEBUG","request running: "+request.getTag().toString());
return true;
}
});
Ответ 4
Какой тег вы использовали при оформлении запросов? Если вы не установили тег для каждого из своих запросов, он может никогда не работать. Насколько я вижу, Volley НЕ автоматически устанавливает тег для ваших запросов
Ответ 5
Если вы добавляете запрос в очередь из фрейммента, вы должны отменить следующее: mRequestQueue.cancelAll(this)
. И жаль, если это не сработало - я не тестировал это решение. Но я надеюсь, что эта помощь вам поможет.
Ответ 6
Вы настраиваете тег запросов на активность? Это единственный способ, которым код, который вы предоставляете, будет работать. Метод cancelAll ищет все запросы с тегом любого тега, который вы предоставили, и отменяет их.
Ответ 7
Проверьте эту статью. Он использует Oto как одиночную шину событий. Таким образом вы можете уведомить очередь залпов, когда ваша активность или фрагменты будут воссозданы. Конечно, вы можете использовать простой старый интерфейс и слушать изменения. BUt Отто выглядит гораздо менее подробным и элегантным, как унифицированное решение.
http://andraskindler.com/blog/2013/eventbus-in-android-an-otto-example/
Ответ 8
В случае фрагмента;
Используйте только один
RequestQueue rQueue;
Инициализируйте его в OnCreate method;
И используйте его для всех запросов волейбола;
и в конце
@Override
public void onStop () {
super.onStop();
if (rQueue != null) {
rQueue.cancelAll(this);
}
}