Une introduction à Volley

Volley est une bibliothèque de réseau développée par Google et introduite au cours de Google I / O 2013. Elle a été développée en raison de l'absence, dans le SDK Android, d'une classe de réseau capable de travailler sans interférer avec l'expérience utilisateur..

Jusqu'à la sortie de Volley, la classe canonique Java java.net.HttpURLConnection et l'apache org.apache.http.client étaient les seuls outils à la disposition des programmeurs Android pour développer un système RESTful entre un client et un serveur distant.

Mettant de côté un instant le fait que ces deux classes ne sont pas exemptes de bogues, il convient de noter que tout ce qui dépassait une simple transaction HTTP devait être écrit ex novo.Si vous vouliez mettre en cache des images ou hiérarchiser les demandes, vous deviez les développer à partir de zéro..

Heureusement, il existe maintenant Volley, créé et adapté pour répondre à ces besoins.

1. Pourquoi Volley?

Éviter HttpUrlConnection et HttpClient

Sur des niveaux d'IPA inférieurs (principalement sur Gingerbread et Froyo), HttpUrlConnection et HttpClient sont loin d'être parfaits. Il y a des problèmes connus et des bugs qui n'ont jamais été corrigés. en outre, HttpClient était obsolète dans la dernière mise à jour de l'API (API 22), ce qui signifie qu'elle ne sera plus maintenue et qu'elle pourra être supprimée dans une version ultérieure.

C’est une raison suffisante pour choisir de passer à un moyen plus fiable de traiter vos requêtes réseau..

Et éviter AsyncTask Aussi

Depuis l'introduction de Honeycomb (API 11), il est devenu obligatoire d'exécuter des opérations réseau sur un thread distinct, différent du thread principal. Ce changement substantiel a ouvert la voie à une utilisation massive du AsyncTask spécification.

Avec AsyncTask, vous définissez d’abord des actions préparatoires, telles que la définition du contexte, onPreExecute. Vous effectuez ensuite vos tâches asynchrones à l’aide de la touche doInBackground méthode. Enfin, vous gérez les résultats en onPostExecute. C'est assez simple, bien plus facile que la mise en œuvre d'un service, et vient avec une tonne d'exemples et de documentation..

Le problème principal, cependant, est la sérialisation des appels. En utilisant le AsyncTask classe, vous ne pouvez pas décider quelle requête va commencer et laquelle doit attendre. Tout se passe FIFO, premier entré, premier sorti.

Les problèmes se posent, par exemple, lorsque vous devez charger une liste d’éléments auxquels une vignette est attachée. Lorsque l'utilisateur fait défiler l'écran vers le bas et attend de nouveaux résultats, vous ne pouvez pas indiquer à votre activité de charger d'abord le fichier JSON de la page suivante, puis uniquement les images de la précédente. Cela peut devenir un sérieux problème d’expérience utilisateur dans des applications telles que Facebook ou Twitter, où la liste des nouveaux éléments est plus importante que la vignette associée..

Volley vise à résoudre ce problème en incluant une API d'annulation puissante. Vous n'avez plus besoin de vous enregistrer onPostExecute si l'activité a été détruite pendant l'exécution de l'appel. Cela aide à éviter un indésirable NullPointerException.

C'est beaucoup plus rapide

Il y a quelque temps, l'équipe de Google+ a effectué une série de tests de performances sur chacune des différentes méthodes permettant d'effectuer des requêtes réseau sur Android. Volley obtient un score jusqu'à dix fois supérieur aux autres alternatives lorsqu'il est utilisé dans des applications RESTful.

Il cache tout

Volley met automatiquement les demandes en cache, ce qui sauve des vies. Revenons un instant à l'exemple que j'ai donné plus tôt. Vous avez une liste d'éléments (un tableau JSON, par exemple), et chaque élément est associé à une description et à une vignette. Pensez maintenant à ce qui se passe si l'utilisateur fait pivoter l'écran: l'activité est détruite, la liste est téléchargée à nouveau, de même que les images. Bref récit, gaspillage important de ressources et mauvaise expérience utilisateur.

Volley s'avère extrêmement utile pour surmonter ce problème. Il se souvient les appels précédents qu'il a fait et gère l'activité de destruction et de reconstruction. Il cache tout sans que vous ayez à vous en soucier.

Petites opérations de métadonnées

Volley est parfaitpour les petits appels, tels que les objets JSON, les portions de liste, les détails d'un élément sélectionné, etc. Il a été conçu pour les applications RESTful et dans ce cas particulier, il donne le meilleur.

Ce n'est pas si bon, cependant, lorsqu'il est utilisé pour les opérations de streaming et les gros téléchargements. Contrairement aux idées reçues, le nom de Volley ne provient pas du dictionnaire des sports. Il s'agit plutôt d'une série d'appels répétés, regroupés. C’est en quelque sorte intuitif pourquoi cette bibliothèque n’est pas pratique quand, au lieu d’une volée de flèches, vous voulez tirer un boulet de canon.

2. sous le capot

Volley fonctionne sur trois niveaux différents, chaque niveau fonctionnant sur son propre fil.

Fil principal

Sur le fil principal, en cohérence avec ce que vous faites déjà dans le AsyncTask spécification, vous êtes uniquement autorisé à déclencher la demande et à gérer sa réponse. Ni plus ni moins.

La conséquence principale est que vous pouvez réellement ignorer tout ce qui se passait dans le doInBackground méthode. Volley gère automatiquement les transactions HTTP et les erreurs de réseau capturantes dont vous deviez vous occuper auparavant..

Cache et threads réseau

Lorsque vous ajoutez une demande à la file d'attente, plusieurs choses se passent sous le capot. Tout d'abord, Volley vérifie si la demande peut être traitée à partir du cache. Si c'est le cas, la réponse en cache est lue, analysée et livrée. Sinon, il est transmis au thread réseau.

Sur le thread réseau, un round-robin avec une série de threads fonctionne en permanence. Le premier thread réseau disponible élimine la file d'attente, effectue la requête HTTP, analyse la réponse et l'écrit dans le cache. Pour finir, il envoie la réponse analysée au thread principal où vos auditeurs attendent pour gérer le résultat..

3. Commencer

Étape 1: Importer Volley

Volley n'est pas si pratique à mettre en place. Il semble qu’il n’y ait pas de référentiel officiel Maven disponible, ce qui est assez déroutant. Vous devez compter sur le code source officiel. Vous pouvez importer Volley de plusieurs façons..

Commençons par télécharger les sources de Volley à partir de son référentiel. Si vous vous sentez confiant de le faire, ce Gitcommande peut faire tout le travail pour vous:

git clone https://android.googlesource.com/platform/frameworks/volley

Jusqu'à il y a quelques semaines, vous pouviez tout emballer en utilisant le fourmi ligne de commande (projet de mise à jour Android -p . et alors fourmilière) et importer votre POT bibliothèque dans votre projet Android Studio avec un simple compiler des fichiers ('libs / volley.jar').

Récemment, cependant, Google a mis à jour Volley avec le style de construction Android Studio, ce qui rend plus difficile la création de POT. Vous pouvez toujours le faire, mais uniquement avec les anciennes versions de la bibliothèque. Personnellement, je vous décourage d’utiliser cette option, même si elle peut sembler la plus rapide..

Vous devriez configurer Volley the manière classique, c'est-à-dire qu'en important la source en tant que module. Dans Android Studio, avec votre projet ouvert, sélectionnez Fichier> Nouveau module, et choisir Importer un projet existant. Sélectionnez le répertoire où vous venez de télécharger le code source et validez. Un dossier nommé Volley apparaîtra dans la structure de votre projet. Android Studio met automatiquement à jour votre paramètres.gradle fichier pour inclure le module Volley afin que vous ayez juste à ajouter à vos dépendances compiler le projet (': volley') et tu as fini.

Il y a une troisième voie. Vous pouvez ajouter à la section de dépendance de la build.gradle déposer cette ligne:

compiler 'com.mcxiaoke.volley: library-aar: 1.0.15'

Il s'agit d'une copie miroir du référentiel Google officiel, régulièrement synchronisé et mis à jour. C'est probablement le moyen le plus simple et le plus rapide de commencer. Cependant, soyez conscient, c'est un non officiel Dépôt Maven, pas de garantie et non sauvegardé par Google.

À mon avis, il est préférable d'investir quelques minutes de plus dans l'importation du code source officiel. De cette façon, vous pouvez facilement accéder aux définitions et implémentations d'origine afin qu'en cas de doute, vous puissiez toujours vous fier à la source officielle Volley et même la modifier si vous en avez besoin..

Étape 2: Utiliser Volley

Volley fonctionne principalement avec deux classes seulement, RequestQueue et Demande. Vous créez d'abord un RequestQueue, qui gère les threads de travail et renvoie les résultats analysés au thread principal. Vous passez ensuite un ou plusieurs Demande objets.

le Demande Le constructeur prend toujours comme paramètres le type de méthode (GET, POST, etc.), l’URL de la ressource et les écouteurs d’événements. Ensuite, en fonction du type de demande, il peut demander des variables supplémentaires.

Dans l'exemple suivant, je crée un RequestQueueobject en invoquant l'une des méthodes pratiques de Volley, Volley.newRequestQueue. Cela met en place un RequestQueueobjet, en utilisant les valeurs par défaut définies par Volley.

String url = "http://httpbin.org/html"; // Demander une réponse sous forme de chaîne StringRequest stringRequest = new StringRequest (Request.Method.GET, url, new Response.Listener() @Override public void onResponse (Réponse en chaîne) // Gestion des résultats System.out.println (response.substring (0,100)); , new Response.ErrorListener () @Override public void onErrorResponse (erreur VolleyError) // Erreur lors de la gestion de System.out.println ("Une erreur s'est produite!"); error.printStackTrace (); ); // Ajoute la demande à la file d'attente Volley.newRequestQueue (this) .add (stringRequest); 

Comme vous pouvez le constater, c'est incroyablement simple. Vous créez la demande et l'ajoutez à la file d'attente des demandes. Et tu as fini.

Notez que la syntaxe d'écoute est similaire à AsyncTask.onPostExecute, il devient simplement onResponse. Ce n'est pas une coïncidence. Les développeurs qui ont travaillé sur Volley ont volontairement rendu l’API de la bibliothèque si semblable au AsyncTask méthodes. Cela rend la transition de l'utilisation AsyncTask Volley beaucoup plus facile.

Si vous devez envoyer plusieurs demandes dans plusieurs activités, évitez d'utiliser l'approche ci-dessus., Volley.newRequestQueue.add. C'est tropIl est préférable d’instancier une file d’attente partagée et de l’utiliser dans votre projet:

MySingletonClass.getInstance (). GetRequestQueue (). Add (myRequest);

Nous verrons spécifiquement à développer quelque chose comme ça dans le prochain tutoriel de cette série.

4. Mettez vos mains dans la pâte

Traitement des demandes standard

Volley est pratique pour implémenter trois types de requêtes très courantes:

  • StringRequest
  • ImageRequest
  • JsonRequest

Chacune de ces classes prolonge la Résultat classe que nous avons utilisée plus tôt. Nous avons déjà regardé le StringRequest dans l'exemple précédent. Voyons à la place comment JsonRequest travaux.

String url = "http://httpbin.org/get?site=code&network=tutsplus"; JsonObjectRequest jsonRequest = new JsonObjectRequest (Request.Method.GET, url, null, new Response.Listener() @Override public void onResponse (réponse JSONObject) // la réponse est déjà construite en tant que JSONObject! try response = response.getJSONObject ("args"); String site = response.getString ("site"), network = response.getString ("réseau"); System.out.println ("Site:" + site + "\ nRéseau:" + réseau);  catch (JSONException e) e.printStackTrace (); , new Response.ErrorListener () @Override public void onErrorResponse (erreur VolleyError) error.printStackTrace (); ); Volley.newRequestQueue (this) .add (jsonRequest);

Belle. N'est-ce pas? Comme vous pouvez le constater, le type de résultat est déjà défini sur JSONObject. Vous pouvez demander un JSONArray aussi si vous voulez, en utilisant un JsonArrayRequest au lieu d'une JsonObjectRequest.

Comme précédemment, le premier paramètre du constructeur est la méthode HTTP à utiliser. Vous fournissez ensuite l'URL à partir de laquelle extraire le JSON. La troisième variable dans l'exemple ci-dessus est nul. Cela convient car cela indique qu'aucun paramètre ne sera publié avec la demande. Enfin, vous avez l’auditeur pour recevoir la réponse JSON et un écouteur d’erreur. Vous pouvez passer nul si vous voulez ignorer les erreurs.

Récupérer des images nécessite un peu plus de travail. Il existe trois méthodes possibles pour demander une image.. ImageRequestest le standard. Il affiche la photo que vous avez demandée dans un format commun ImageView, le récupérer via une URL fournie. Toutes les opérations de décodage et de redimensionnement que vous pouvez souhaiter que Volley exécute se produisent sur un thread de travail. La deuxième option est la ImageLoader classe, que vous pouvez penser comme un orchestrateur d’un grand nombre de ImageRequests, par exemple, pour peupler un ListView avec des images. La troisième option est NetworkImageView, qui est une sorte de substitut XML pour le ImageView élément de mise en page.

Regardons un exemple.

String url = "http://i.imgur.com/Nwk25LA.jpg"; mImageView = (ImageView) findViewById (R.id.image); ImageRequest imgRequest = new ImageRequest (url, new Response.Listener() @Override public void onResponse (réponse bitmap) mImageView.setImageBitmap (réponse); , 0, 0, ImageView.ScaleType.FIT_XY, Bitmap.Config.ARGB_8888, nouvelle Response.ErrorListener () @Override public void onErrorResponse (erreur VolleyError) mImageView.setBackgroundColor (Color.parseColor) ; error.printStackTrace (); ); Volley.newRequestQueue (this) .add (imgRequest);

Le premier paramètre est l'URL de l'image et le second est l'écouteur du résultat. Les troisième et quatrième paramètres sont des entiers, largeur maximale et hauteur maximum. Vous pouvez les configurer pour 0 ignorer ces paramètres. Après ça, ImageRequestvous demande le ScaleType utilisé pour calculer la taille d'image nécessaire et pour le format de décodage du bitmap. Je suggère d'utiliser toujours Bitmap.Config.ARGB_8888. Enfin, nous passons dans un listener d'erreur.

Notez que Volley définit automatiquement la priorité de cette demande sur FAIBLE.

// Extrait extrait de ImageRequest.java, // dans le code source Volley @Override public Priority getPriority () return Priority.LOW; 

Faire une demande POST

Passer d'une requête GET à une requête POST est simple. Vous devez changer le Demande.Méthode dans le constructeur de la demande et remplacer le getParams méthode, retournant un bon Carte contenant les paramètres de la requête.

String url = "http://httpbin.org/post"; StringRequest postRequest = new StringRequest (Request.Method.POST, url, new Response.Listener() @Override public void onResponse (réponse en chaîne) try JSONObject jsonResponse = new JSONObject (réponse) .getJSONObject ("form"); String site = jsonResponse.getString ("site"), réseau = jsonResponse.getString ("réseau"); System.out.println ("Site:" + site + "\ nRéseau:" + réseau);  catch (JSONException e) e.printStackTrace (); , new Response.ErrorListener () @Override public void onErrorResponse (erreur VolleyError) error.printStackTrace (); ) @Override protected Map getParams () Carte params = new HashMap <> (); // les paramètres du POST: params.put ("site", "code"); params.put ("réseau", "tutsplus"); retourne params; ; Volley.newRequestQueue (this) .add (postRequest);

Annuler une demande

Si vous souhaitez annuler toutes vos demandes, ajoutez l'extrait de code suivant à la onStop méthode:

@Override protected void onStop () super.onStop (); mRequestQueue.cancelAll (new RequestQueue.RequestFilter () @Override public boolean apply (Request request) // dois-je annuler cela? retourne vrai; // -> toujours oui); 

De cette façon, vous n’aurez plus à craindre que l’utilisateur ait déjà détruit l’activité lorsque onResponse est appelé. UNE NullPointerException serait jeté dans un tel cas.

Les requêtes POST et PUT doivent toutefois continuer même après le changement d'activité de l'utilisateur. Nous pouvons accomplir cela en utilisant Mots clés. Lors de la construction d'une requête GET, ajoutez-y une balise.

// après avoir déclaré votre requête request.setTag ("GET"); mRequestQueue.add (demande);

Pour annuler chaque requête GET en attente, nous ajoutons simplement la ligne de code suivante:

mRequestQueue.cancelAll ("GET");

De cette façon, vous annulez uniquement les demandes GET, en laissant les autres demandes intactes. Notez que vous devez maintenant gérer manuellement le cas dans lequel l'activité est détruite prématurément..

Gestion des cookies et priorité des demandes

Volley ne fournit pas de méthode pour configurer les cookies d'une requête, ni sa priorité. Ce sera probablement le cas à l'avenir, car c'est une grave omission. Pour le moment, cependant, vous devez prolonger Demande classe.

Pour gérer les cookies, vous pouvez jouer avec les en-têtes de la demande, en remplaçant le getHeaders méthode:

classe publique CustomRequest étend JsonObjectRequest // Comme nous étendons une classe Request // nous utilisons simplement son constructeur public CustomRequest (méthode int, String url, JSONObject jsonRequest, Response.Listener écouteur, Response.ErrorListener errorListener) super (méthode, url, jsonRequest, écouteur, errorListener);  Carte privée en-têtes = new HashMap <> (); / ** * Cours personnalisé! * / public void setCookies (Liste cookies) StringBuilder sb = new StringBuilder (); for (Chaîne cookie: cookies) sb.append (cookie) .append (";");  headers.put ("Cookie", sb.toString ());  @Override public Map getHeaders () lève AuthFailureError en-têtes de retour; 

Avec cette implémentation, vous pouvez directement fournir la liste des cookies à la demande en utilisant setCookies.

// Tout d'abord, vous créez la liste des cookies, // conforme aux conventions HTTP // i.e. key = value List cookies = new ArrayList <> (); cookies.add ("site = code"); cookies.add ("network = tutsplus"); // alors vous appelez votre méthode personnalisée customRequest.setCookies (cookies); // et enfin ajouter la demande à la file d'attente Volley.newRequestQueue (this) .add (customRequest);

Pour la priorité, vous devez également étendre la Demande classe, annulant la obtenir la priorité méthode. Voici à quoi pourrait ressembler l'implémentation:

Priorité prioritaire; public void setPriority (priorité prioritaire) mPriority = priorité;  @Override public Priority getPriority () // Si vous n'avez pas utilisé la méthode setPriority, // la priorité est automatiquement définie sur NORMAL return mPriority! = Null? mPriority: Priority.NORMAL; 

Ensuite, sur le thread principal, appelez cette ligne de code pour définir la priorité de la demande:

customRequest.setPriority (Priority.HIGH);

Vous pouvez choisir l'un des quatre états de priorité possibles, comme indiqué ci-dessous:

Priority.LOW // images, vignettes,… Priority.NORMAL // priorité résiduelle.HIGH // descriptions, listes,… Priority.IMMEDIATE // connexion, déconnexion,… 

Conclusion

Dans cet article, nous avons examiné le fonctionnement de la bibliothèque de réseaux Volley. Nous avons d'abord compris pourquoi et quand il était préférable d'utiliser Volley au lieu d'une autre solution déjà incluse dans le SDK Android. Nous avons ensuite plongé dans les détails de la bibliothèque, en examinant son flux de travail et les types de demande pris en charge. Enfin, nous nous sommes salués les mains en créant des requêtes simples et en implémentant des requêtes personnalisées pour la gestion des cookies et la définition des priorités..

Dans la prochaine partie de cette série sur Volley, nous allons créer une application simple qui exploite Volley. Je vais vous montrer comment créer une application météo pour Mars, en utilisant les données météorologiques collectées sur Mars par le rover Curiosity..

Si vous développez beaucoup d'Android, pourquoi ne pas accélérer votre flux de travail en utilisant l'un des milliers de modèles d'applications Android utiles disponibles sur Envato Market? Ou contactez l'un des développeurs Android sur Envato Studio pour vous aider dans votre projet. Ils peuvent même concevoir votre application pour vous à partir de la base.!