web-dev-qa-db-fra.com

Annuler toutes les demandes de volley Android

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?

20
EkKoZ

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.

56
mogi57

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
17
pjco

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;
        }
});
4
Lefteris

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.

3
Zh. Atanasov

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/

0
greenspand

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);
    }
}
0
Purva Naik

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.

0
Pieces

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.

0
senneco