Envoi de données avec le client HTTP Retrofit 2 pour Android

Ce que vous allez créer

Qu'est-ce que la modernisation??

Retrofit est un client HTTP de type sécurisé pour Android et Java. Retrofit facilite la connexion à un service Web REST en traduisant l'API en interfaces Java. Dans ce tutoriel, je vais vous montrer comment utiliser l'une des bibliothèques HTTP les plus populaires et les plus recommandées disponibles pour Android..

Cette puissante bibliothèque facilite la consommation de données JSON ou XML, qui sont ensuite analysées dans des objets POJO (Plain Old Java Objects).. OBTENIRPOSTERMETTREPIÈCE, et EFFACER les demandes peuvent toutes être exécutées. 

Comme la plupart des logiciels open-source, Retrofit s’est construit sur d’autres bibliothèques et outils puissants. Retrofit utilise en arrière plan OkHttp (du même développeur) pour gérer les requêtes réseau. De plus, Retrofit ne dispose pas d'un convertisseur JSON intégré pour analyser des objets JSON en objets Java. Au lieu de cela, il prend en charge les bibliothèques de conversion JSON suivantes pour gérer cela:

  • Gson: com.squareup.retrofit: convertisseur-gson
  • Jackson: com.squareup.retrofit: convertisseur-jackson
  • Moshi: com.squareup.retrofit: convertisseur-moshi

Retrofit prend en charge les tampons de protocole suivants:

  • Protobuf: com.squareup.retrofit2: converter-protobuf
  • Câble: com.squareup.retrofit2: convertisseur de fil

Et pour XML Retrofit, prend en charge:

  • Cadre simple: com.squareup.retrofit2: convertisseur-simpleframework

Alors pourquoi utiliser Retrofit?

Il peut être très difficile de développer votre propre bibliothèque HTTP sécurisée pour une interface avec une API REST: vous devez gérer de nombreux aspects, tels que l'établissement de connexions, la mise en cache, la nouvelle tentative de demandes échouées, le threading, l'analyse des réponses, la gestion des erreurs, etc. Retrofit, en revanche, est une bibliothèque bien planifiée, documentée et testée qui vous fera économiser beaucoup de temps précieux et de maux de tête..

Dans ce tutoriel, je vais expliquer comment utiliser Retrofit 2 pour gérer les demandes réseau en construisant une application simple POSTER demandes, METTRE demandes (pour mettre à jour des entités), et EFFACER demandes. Je vais également vous montrer comment intégrer RxJava et comment annuler des demandes. Nous utiliserons l'API fournie par JSONPlaceholder. Il s'agit d'une fausse API REST en ligne pour les tests et le prototypage..

Consultez mon article précédent, Démarrer avec le client HTTP Retrofit 2, pour apprendre à exécuter OBTENIR demandes et comment intégrer Retrofit avec RxJava. 

1. Créer un projet Android Studio

Lancez Android Studio et créez un nouveau projet avec une activité vide appelée Activité principale.

2. Déclaration de dépendances

Après avoir créé un nouveau projet, déclarez les dépendances suivantes dans votre build.gradle. Les dépendances incluent la bibliothèque Retrofit ainsi que la bibliothèque Gson de Google pour convertir le JSON en POJO (Plain Old Java Objects), ainsi que pour l'intégration Gson de Retrofit.. 

// Retrofit compile 'com.squareup.retrofit2: retrofit: 2.1.0' // // Compilation JSON 'com.google.code.gson: gson: 2.6.1' compile 'com.squareup.retrofit2: convertisseur-gson: 2.1 0.0 '

Assurez-vous de synchroniser votre projet après avoir ajouté les dépendances.. 

3. Ajouter une autorisation Internet

Pour effectuer des opérations sur le réseau, nous devons inclure la L'INTERNET autorisation dans le manifeste d'application: AndroidManifest.xml.

           

4. Génération automatique de modèles

Nous allons créer des modèles automatiquement à partir des données de réponse JSON en utilisant un outil très utile: jsonschema2pojo. Nous aimerions faire un POSTER demander (créer une nouvelle ressource) sur l'API. Mais avant d'exécuter cette demande, nous devons connaître la réponse JSON à laquelle elle doit s'attendre lorsqu'elle sera exécutée avec succès, afin que Retrofit puisse analyser la réponse JSON et la désérialiser en objets Java. Selon l’API, si on envoie les données suivantes dans un fichier POSTER demande:

données: titre: 'foo', corps: 'bar', userId: 1

Nous devrions obtenir la réponse suivante:

"title": "foo", "body": "bar", "userId": 1, "id": 101

Mapper les données JSON vers Java 

Copiez les exemples de données de réponse de la section précédente. Maintenant, visitez jsonschema2pojo et collez la réponse JSON dans la zone de saisie. Sélectionnez le type de source de JSON, style d'annotation de Gson, décocher Autoriser des propriétés supplémentaires, et changer le nom de la classe de Exemple à Poster

Puis cliquez sur le Aperçu bouton pour générer les objets Java. 

Vous pourriez vous demander ce que le @SerializedName et @Exposer les annotations font dans ce code généré! Ne vous inquiétez pas, je vais tout expliquer!

le @SerializedName une annotation est nécessaire pour que Gson mappe les clés JSON aux champs d'objet Java.

@SerializedName ("userId") @Expose private Integer userId;

Dans ce cas, la clé JSON identifiant d'utilisateur est mappé au champ de classe identifiant d'utilisateur. Mais notez que, comme elles sont identiques, il n’est pas nécessaire d’inclure les @SerializedName annotation sur le terrain parce que Gson mappera automatiquement pour nous.

le @Exposer une annotation indique que le membre de la classe doit être exposé pour la sérialisation ou la désérialisation JSON. 

Importer des modèles de données vers Android Studio

Revenons maintenant à Android Studio. Créer un nouveau sous-package dans le principale paquet et nommez-le Les données. Dans le paquet nouvellement créé, créez un autre paquet et nommez-le. modèle. Dans ce package, créez une nouvelle classe Java et nommez-la. Poster. Maintenant, copiez le Poster classe qui a été générée par jsonschema2pojo et collée à l'intérieur du Poster classe que vous avez créée. 

package com.chikeandroid.retrofittutorial2.data.model; importer com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; Classe publique Post @SerializedName ("title") @Expose private String title; @SerializedName ("body") @Expose private String body; @SerializedName ("userId") @Expose private Integer userId; @SerializedName ("id") @Expose private ID entier; public String getTitle () return title;  public void setTitle (Titre de la chaîne) this.title = title;  public String getBody () return body;  public void setBody (Corps de la chaîne) this.body = body;  public Integer getUserId () return userId;  public void setUserId (Integer userId) this.userId = userId;  public Integer getId () return id;  public void setId (Integer id) this.id = id;  @Override public String toString () return "Post " + "title = '" + title +' \ "+", + body + "\" + ", userId =" + userId + ", / posts") @FormUrlEncoded Call savePost (@Field ("title") Titre de la chaîne, @Field ("body") Corps de la chaîne, @Field ("userId") long userId); 

En regardant le APIService classe, nous avons une méthode appelée savePost (). En plus de la méthode est le @POSTER annotation, qui indique que nous voulons exécuter un POSTER demande quand cette méthode est appelée. La valeur de l'argument pour le @POSTER l'annotation est le point final qui est /des postes. Donc, l'URL complète sera http://jsonplaceholder.typicode.com/posts. 

Ok, alors qu'en est-il du @FormUrlEncoded? Cela indiquera que le type MIME de la demande (un champ d’en-tête qui identifie le format du corps d’une demande ou d’une réponse HTTP) est défini sur application / x-www-form-urlencoded et aussi que ses noms de champs et ses valeurs seront codés en UTF-8 avant d’être codés en URI. le @Field ("clé") L'annotation avec le nom du paramètre doit correspondre au nom attendu par l'API. Retrofit convertit implicitement les valeurs en chaînes en utilisant String.valueOf (Object), et les chaînes sont ensuite encodées sous forme d'URL de formulaire. nul les valeurs sont ignorées. 

Par exemple, appeler APIService.savePost ("Ma visite à Lagos", "J'ai visité…", 2) donne un corps de requête de title = Mon + Visite + À + Lagos & body = I + visité… & userId = 2.

En utilisant le @Corps Annotation

Nous pouvons aussi utiliser le @Corps annotation sur un paramètre de méthode de service au lieu de spécifier un corps de requête de type formulaire avec un certain nombre de champs individuels. L'objet sera sérialisé en utilisant le Retrofit exemple Convertisseur spécifié lors de la création. Ceci est utilisé uniquement lors de l'exécution d'un POSTER ou METTRE opération. 

@POST ("/ posts") @FormUrlEncoded Call savePost (@Body Post);

7. Création des utilitaires d'API

Nous allons créer une classe d'utilitaire. Alors créez une classe dans data.remote et nommez-le ApiUtils. Cette classe aura l’URL de base en tant que variable statique et fournira également le APIService interface par un getAPIService () méthode statique pour le reste de notre application.

package com.chikeandroid.retrofittutorial2.data.remote; public class ApiUtils privé ApiUtils ()  public final final String BASE_URL = "http://jsonplaceholder.typicode.com/"; public statique APIService getAPIService () return RetrofitClient.getClient (BASE_URL) .create (APIService.class); 

Assurez-vous de terminer l'URL de base avec un /

8. Créer la mise en page

Le fichier activity_main.xml est la mise en page pour notre Activité principale. Cette mise en page comportera un champ de saisie de texte pour le titre du message et un autre pour le corps du message. Il comprend également un bouton pour soumettre le message à l'API. 

     

9. Exécuter la requête POST

dans le onCreate () méthode en Activité principale, nous initialisons une instance du APIService interface (ligne 14). Nous initialisons également le Éditer le texte des champs et un bouton d'envoi qui appelle le sendPost () méthode lorsque vous cliquez dessus (ligne 22).

TextView privé mResponseTv; APIService privé mAPIService; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); final EditText titleEt = (EditText) findViewById (R.id.et_title); final EditText bodyEt = (EditText) findViewById (R.id.et_body); Bouton submitBtn = (Bouton) findViewById (R.id.btn_submit); mResponseTv = (TextView) findViewById (R.id.tv_response); mAPIService = ApiUtils.getAPIService (); submitBtn.setOnClickListener (new View.OnClickListener () @Override public void onClick (Affichage de la vue) String title = titleEt.getText (). toString (). trim (); String body = bodyEt.getText (). toString (). .trim (); if (! TextUtils.isEmpty (titre) &&! TextUtils.isEmpty (corps)) sendPost (titre, corps);); 

dans le sendPost (String, String) méthode dans le Activité principale classe, nous avons passé le titre et le corps du message à cette méthode. Ce que cette méthode fera est d'appeler notre méthode d'interface de service API savePost (String, String) dont le travail consiste à exécuter un POSTER demander l'envoi du titre et du corps à l'API. le showResponse (réponse en chaîne) la méthode affichera la réponse à l'écran.

public void sendPost (Titre de la chaîne, Corps de la chaîne) mAPIService.savePost (title, body, 1) .enqueue (new Callback() @Override public void onResponse (Call appel, réponse réponse) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "publication soumise à l'API". + Response.body (). ToString ());  @Override public void onFailure (Appeler call, Throwable t) Log.e (TAG, "Impossible de soumettre une publication à l'API."); );  public void showResponse (Réponse en chaîne) if (mResponseTv.getVisibility () == View.GONE) mResponseTv.setVisibility (View.VISIBLE);  mResponseTv.setText (response); 

Notre APIService exemple mAPIService méthode savePost (String, String) retournera un Appel instance qui a une méthode appelée mettre en file d'attente rappeler).

Compréhension enqueue ()

enqueue () envoie la demande de manière asynchrone et informe votre application par un rappel lorsque la réponse est renvoyée. Dans la mesure où cette demande est asynchrone, Retrofit gère l’exécution sur un thread d’arrière-plan afin que le thread principal de l’interface utilisateur ne soit ni bloqué ni perturbé.. 

Pour utiliser le enqueue () méthode, vous devez implémenter deux méthodes de rappel: onResponse () et onFailure (). Une seule de ces méthodes sera appelée en réponse à une requête donnée. 

  • onResponse (): appelé pour une réponse HTTP reçue. Cette méthode est appelée pour une réponse qui peut être traitée correctement même si le serveur renvoie un message d'erreur. Donc, si vous obtenez un code d'état de 404 ou 500, cette méthode sera toujours appelée. Pour obtenir le code de statut afin de pouvoir gérer des situations basées sur celles-ci, vous pouvez utiliser la méthode Code de réponse(). Vous pouvez également utiliser le est réussi() méthode permettant de savoir si le code d'état est compris entre 200 et 300, indiquant le succès.
  • onFailure (): invoqué lorsqu'une exception réseau s'est produite lors de la communication avec le serveur ou lorsqu'une exception inattendue s'est produite lors du traitement de la demande ou du traitement de la réponse.

Requêtes Synchrones

Pour effectuer une requête synchrone, vous pouvez utiliser le exécuter() méthode dans un Appel exemple. Sachez toutefois que les méthodes synchrones sur le thread principal / d'interface utilisateur bloquent toute action de l'utilisateur. Donc, n'exécutez pas de méthodes synchrones sur le thread principal / interface utilisateur d'Android! Au lieu de les exécuter sur un fil de fond.

Utiliser RxJava 

RxJava a été intégré par défaut à Retrofit 1, mais dans Retrofit 2, vous devez inclure des dépendances supplémentaires. Retrofit est livré avec un adaptateur par défaut pour l'exécution Appel les instances. Vous pouvez donc modifier le mécanisme d’exécution de Retrofit pour inclure RxJava en incluant le fichier RxJava. CallAdapter. Ce sont les étapes:

Étape 1

Ajouter les dépendances.

compiler 'io.reactivex: rxjava: 1.1.6' compiler 'io.reactivex: rxandroid: 1.2.1' compiler 'com.squareup.retrofit2: adapter-rxjava: 2.1.0'

Étape 2

Ajouter le nouvel CallAdapter RxJavaCallAdapterFactory.create () lors de la construction d'une instance Retrofit (ligne 5).  

public statique Retrofit getClient (String baseUrl) if (retrofit == null) retrofit = new Retrofit.Builder () .baseUrl (baseUrl) .addCallAdapterFactory (RxJavaCallAdapterFactory.create ()) .addConverterFactory (GsonConverterFactory (GsonConverterFactory). ();  retour ultérieur; 

Étape 3

Mettre à jour le APIService savePost (Titre de la chaîne, Corps de la chaîne, ID utilisateur de la chaîne) méthode pour devenir un observable. 

@POST ("/ posts") @FormUrlEncoded Observable savePost (@Field ("title") Titre de la chaîne, @Field ("body") Corps de la chaîne, @Field ("userId") long userId);

Étape 4

Lors de la demande, notre abonné anonyme répond au flux de l'observable qui émet des événements, dans notre cas Poster. le onNext La méthode est ensuite appelée lorsque notre abonné reçoit un événement, qui est ensuite transmis à notre showResponse (réponse en chaîne) méthode. 

public void sendPost (Titre de la chaîne, Corps de la chaîne) // RxJava mAPIService.savePost (titre, corps, 1) .subscribeOn (Schedulers.io ()). observeOn (AndroidSchedulers.mainThread ()) .subscribe (nouvel abonné() @Override public nul onCompleted ()  @Override public vide onError (Throwable e)  @Override public nul onNext (Post post) showResponse (post.toString ()); ); 

Découvrez Premiers pas avec ReactiveX sur Android par Ashraff Hathibelagal pour en savoir plus sur RxJava et RxAndroid.. 

10. Test de l'application

À ce stade, vous pouvez exécuter l'application et cliquer sur le bouton Soumettre lorsque vous avez saisi un titre et un corps. La réponse de l'API s'affichera sous le bouton d'envoi. 

11. Exécuter une requête PUT

Maintenant que nous savons exécuter un POSTER demande, voyons comment nous pouvons exécuter un METTRE demande qui met à jour les entités. Ajouter la nouvelle méthode suivante à la APIService classe. 

@PUT ("/ posts / id") @FormUrlEncoded Call updatePost (@Path ("id") identifiant long, @Field ("titre") Titre de la chaîne, @Field ("corps") Corps de la chaîne, @Field ("userId") identificateur utilisateur long;

Pour mettre à jour un message de l'API, nous avons le point final / posts / id avec id être un espace réservé pour l'id de la publication que nous souhaitons mettre à jour. le @Chemin l'annotation est le remplacement nommé dans un segment de chemin d'URL id. Sachez que les valeurs sont converties en chaîne en utilisant String.valueOf (Object) et une URL encodée. Si la valeur est déjà encodée, vous pouvez désactiver l'encodage d'URL comme ceci: @Path (valeur = "nom", codé = vrai)

12. Exécuter une requête DELETE

Voyons aussi comment exécuter un EFFACER demande. À l’aide de l’API JSONPlaceholder, pour supprimer une ressource de publication, le noeud final requis est / posts / id avec la méthode HTTP EFFACER. Retour à notre APIService interface, nous avons juste besoin d'inclure la méthode Supprimer le message() cela l'exécutera. Nous passons l'id de la publication à la méthode, qui est remplacée dans le segment de chemin d'URL id.

@DELETE ("/ posts / id") Appeler deletePost (@Path ("id") identifiant long);

13. Annuler une demande

Supposons que vous souhaitiez donner à vos utilisateurs la possibilité d'annuler ou d'abandonner une demande. Ceci est très facile à faire dans Retrofit. La rénovation Appel la classe a une méthode appelée Annuler() cela fera exactement cela (ligne 32 ci-dessous). Cette méthode déclenchera la onFailure () méthode dans le rappel. 

Cette méthode peut être appelée, par exemple, s'il n'y a pas de connexion Internet ou lorsqu'une exception inattendue s'est produite lors de la création de la demande ou du traitement de la réponse. Donc, pour savoir si la demande a été annulée, utilisez la méthode est annulé() dans le Appel classe (ligne 20). 

appel privé mCall;… public sendPost (titre de la chaîne, corps de la chaîne) mCall = mAPIService.savePost (title, body, 1); mCall.enqueue (nouveau rappel() @Override public void onResponse (Call appel, réponse réponse) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "publication soumise à l'API". + Response.body (). ToString ());  @Override public void onFailure (Appeler call, Throwable t) if (call.isCanceled ()) Log.e (TAG, "la requête a été abandonnée");  else Log.e (TAG, "Impossible de soumettre une publication à l'API.");  showErrorMessage (); );  public void cancelRequest () mCall.cancel (); 

Conclusion

Dans ce tutoriel, vous avez appris à propos de Retrofit: pourquoi l’utiliser et comment l’intégrer dans votre projet pour POSTERMETTREEFFACER et annuler les demandes. Vous avez également appris à intégrer RxJava à celui-ci. Dans mon prochain article sur l'utilisation de Retrofit, je vais vous montrer comment télécharger des fichiers.. 

Pour en savoir plus sur Retrofit, reportez-vous à la documentation officielle. Et découvrez certains de nos autres tutoriels et cours sur le développement Android ici à Envato Tuts+!

  • Animez votre application Android

    Les animations sont devenues une partie importante de l'expérience utilisateur Android. Une animation subtile et bien conçue est utilisée dans tout le système d'exploitation Android et peut…
    Ashraff Hathibelagal
    Développement mobile
  • Concurrence pratique sur Android avec HaMeR

    Dans ce didacticiel, nous allons explorer le cadre HaMeR (gestionnaire, message et exécutable), l'un des modèles de concurrence les plus puissants disponibles sur Android. Avec un…
    Tin Megali
    SDK Android
  • Codage d'applications Android fonctionnelles dans Kotlin: Mise en route

    Entendu des choses positives sur la langue Kotlin pour les applications Android et que vous voulez l'essayer vous-même? Découvrez comment configurer et commencer à coder dans cette nouvelle…
    Jessica Thornsby
    Studio Android
  • Migrer une application Android vers la conception matérielle

    Il y a des années, lorsque Android était encore un système d'exploitation mobile en herbe, il était plutôt connu pour son interface utilisateur laide. Parce qu'il n'y avait pas de design…
    Ashraff Hathibelagal
    Android