Pour le moment, j'utilise mRequestQueue.cancelAll (getActivity ()) de la méthode on stop dans un fragment, mais apparemment, lorsque je déplace le téléphone de paysage à portrait, il renvoie toujours les données effectuées dans la demande, mais provoque un crash le doseur de données existe plus. un exemple de code de comment le faire correctement?
Au lieu d'utiliser une balise pour cancelAll, créez un RequestFilter tout passe.
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
return true;
}
});
EDIT: Ceci annule toutes les demandes de toutes les activités/fragments et ne fonctionne pas correctement avec le cycle de vie des activités. La meilleure façon de gérer cela consiste à ajouter une balise String unique à votre fragment.
Vous devez définir la balise sur un objet, pas sur une méthode.
En définissant la balise sur getActivity()
, vous demandez à Volley d'utiliser un appel de méthode dynamique sur le thread principal en tant que référence à la demande qui se produit sur un thread en arrière-plan.
Ainsi, lorsque le thread d'arrière-plan tente d'annuler les demandes, l'activité peut déjà être morte.
Plutôt que d'utiliser getActivity()
, utilisez this
ou un autre objet ou une chaîne.
C’est une bonne pratique pour toute balise et vous devez également vous méfier de qui laisse filtrer votre activité.
Solutions:
Vous pouvez utiliser l'objet actuel:
request.setTag(this);
ou, l'objet de classe statique
request.setTag(MyFragment.class);
ou, en tant que constante dans une classe séparée:
request.setTag(CustomTags.LIST_REQUESTS);
CustomTags.LIST_REQUESTS étant le meilleur à mon avis (moins de risque de fuite d'activité)
Quelque chose comme ça:
public class CustomTags
{
public static final String LIST_REQUESTS="CustomTags:LIST_REQUESTS";
}
Mettre à jour
Je viens de remarquer que je commettais une erreur en marquant mes demandes dans Volley (bien que les solutions que j’ai affichées ci-dessus soient correctes).
Je pensais toujours que je mettrais à jour ici une chose importante à garder à l'esprit. Les étiquettes de volley par identity et non value.
Par conséquent, il est important de garder à l'esprit qu'une balise qui est simplement la même valeur de chaîne, et non le même objet lui-même, ne sera pas reconnue comme étant la même tag
.
C'est semblable à la différence entre
String a1 = "A";
String a2 = "A";
a1 == a2; //evaluates to false
String a1 = "A";
String a2 = "A";
a1.equals(a2); // evaluates to true
Je sais que cette réponse arrive en retard, mais au cas où quelqu'un d'autre aurait ce problème:
Dans mon implémentation, la balise était définie (et écrasée) au point où la demande a été ajoutée à la file d'attente.
Donc, malgré l'annulation de la demande avec mon tag, le tag de la file d'attente des demandes n'était pas le même (comme il avait été écrasé précédemment) et il n'a pas été annulé.
L'enregistrement des requêtes en cours d'exécution et l'impression des balises m'ont amené à la solution:
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
@Override
public boolean apply(Request<?> request) {
Log.d("DEBUG","request running: "+request.getTag().toString());
return true;
}
});
Quelle balise avez-vous utilisée lors des demandes? Si vous n'avez pas défini de balise pour chacune de vos demandes, cela pourrait ne jamais fonctionner. Autant que je sache, Volley NE définit PAS automatiquement une étiquette pour vos demandes.
Vérifiez cet article. Il utilise Oto comme bus d'événement singleton. De cette façon, vous pouvez notifier la file d’attente lorsque votre activité ou vos fragments sont recréés. Vous pouvez bien sûr utiliser une ancienne interface simple et écouter les modifications. Mais Otto a l'air beaucoup moins bavard et élégant qu'une solution unifiée.
http://andraskindler.com/blog/2013/eventbus-in-Android-an-otto-example/
En cas de fragment; Utilisez un seul RequestQueue rQueue;
Initialisez-le dans OnCreate method;
Et utilisez-le pour toute demande de volée; .__ et à la fin
@Passer outre
public void onStop () {
super.onStop();
if (rQueue != null) {
rQueue.cancelAll(this);
}
}
Définissez-vous l'étiquette des demandes pour l'activité? C'est la seule façon dont le code que vous fournissez fonctionnera. La méthode cancelAll recherche toutes les demandes avec la balise de la balise que vous avez fournie et les annule.
Si vous ajoutez une demande de file d'attente à partir de fragment, vous devez annuler comme suit: mRequestQueue.cancelAll(this)
. Et désolé si cela n'a pas fonctionné - je n'ai pas testé cette solution. Mais j'espère que cela vous aidera.