Commencer avec le client HTTP Retrofit 2

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 n’a pas de 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

Pour les tampons de protocole, Retrofit prend en charge:

  • 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?

Le développement de votre propre bibliothèque HTTP sécurisée pour une interface avec une API REST peut s'avérer une tâche ardue: vous devez gérer de nombreuses fonctionnalités telles que l'établissement de connexions, la mise en cache, la réessai de demandes échouées, le threading, l'analyse des réponses, la gestion des erreurs, etc. La modernisation, en revanche, est très bien planifiée, documentée et testée - une bibliothèque testée au combat qui vous fera gagner un temps précieux et des maux de tête..

Dans ce didacticiel, je vais expliquer comment utiliser Retrofit 2 pour gérer les demandes réseau en construisant une application simple pour interroger des réponses récentes à partir de l'API Stack Exchange. Nous allons effectuer OBTENIR demandes en spécifiant un noeud final-/réponses, ajouté à l'URL de base https://api.stackexchange.com/2.2/- puis obtenez les résultats et affichez-les dans une vue du recycleur. Je vais également vous montrer comment faire cela avec RxJava pour une gestion facile du flux d'état et de données.

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.gradleLes dépendances comprennent une vue recycleur, la bibliothèque Retrofit, ainsi que la bibliothèque Gson de Google pour convertir le format JSON en POJO (objets Plain Old Java), ainsi que 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 '// recyclerview compile' com.android.support:recyclerview-v7:25.0.1 ' 

N'oubliez pas de synchroniser le projet pour télécharger ces bibliothèques. 

3. Ajouter une autorisation Internet

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

           

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

Nous allons créer nos modèles automatiquement à partir de nos données de réponse JSON en utilisant un outil très utile: jsonschema2pojo.. 

Obtenir les exemples de données JSON

Copiez et collez https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow dans la barre d'adresse de votre navigateur (ou vous pouvez utiliser Postman si vous connaissez cet outil). Puis appuyez Entrer-cela exécutera une demande GET sur le noeud final donné. Ce que vous verrez en réponse est un tableau d'objets JSON. La capture d'écran ci-dessous est la réponse JSON utilisant Postman..

"items": ["owner": "reputation": 1, "user_id": 6540831, "user_type": "registered", "profile_image": "https://www.gravatar.com/avatar/6a468ce8a8ff42c17923a6009ab77723 ? s = 128 & d = identicon & r = PG & f = 1 "," display_name ":" bobolafrite "," link ":" http://stackoverflow.com/users/6540831/bobolafrite "," is_accepted ": false," score " : 0, "last_activity_date": 1480862271, "creation_date": 1480862271, "answer_id": 40959732, "question_id": 35931342, "owner": "reputation": 629, "user_id": 3054722, "user_type": "registered", "profile_image": "https://www.gravatar.com/avatar/0cf65651ae9a3ba2858ef0d0a7dbf900?s=128&d=identicon&r=PG&f=1", "display_name": "jeremy-denis", "lien": "http : //stackoverflow.com/users/3054722/jeremy-denis "," is_accepted ": false," score ": 0," last_activity_date ": 1480862260," creation_date ": 1480862260," answer_id ": 40959731," question_id " : 40959661,…], "has_more": true, "backoff": 10, "quota_max": 300, "quota_remaining": 241

Copiez cette réponse JSON à partir de votre navigateur ou de Postman. 

Mapper les données JSON vers Java

Maintenant, visitez jsonschema2pojo et collez la réponse JSON dans la zone de saisie..

Sélectionnez un type de source de JSON, style d'annotation de Gson, et décocher Autoriser des propriétés supplémentaires

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 avec nos champs. Conformément à la convention de nommage camelCase de Java pour les propriétés de membre de classe, il est déconseillé d'utiliser des traits de soulignement pour séparer les mots d'une variable.. @SerializedName aide à traduire entre les deux.

@SerializedName ("quota_remaining") @Expose private Integer quotaRemaining;

Dans l'exemple ci-dessus, nous disons à Gson que notre clé JSON quota_remaining doit être mappé sur le champ Java quotaRemaining.  Si ces deux valeurs étaient identiques, c’est-à-dire si notre clé JSON était quotaRemaining tout comme le champ Java, il n'y aurait pas besoin de la @SerializedName annotation sur le terrain car Gson les mapperait automatiquement.

le @Exposer une annotation indique que ce membre 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éez un nouveau sous-paquet dans le paquet principal et nommez-le. Les données. Dans le paquet de données nouvellement créé, créez un autre paquet et nommez-le. modèle. Dans le package de modèle, créez une nouvelle classe Java et nommez-la. Propriétaire. Maintenant, copiez le Propriétaire classe qui a été générée par jsonschema2pojo et collée à l'intérieur du Propriétaire classe que vous avez créée. 

importer com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; Classe publique Owner @SerializedName ("reputation") @Expose private Integer reputation; @SerializedName ("user_id") @Expose private Integer userId; @SerializedName ("user_type") @Expose private String userType; @SerializedName ("profile_image") @Expose private String profileImage; @SerializedName ("display_name") @Expose private String displayName; @SerializedName ("link") @Expose private String link; @SerializedName ("accept_rate") @Expose private Integer acceptRate; public Integer getReputation () return réputation;  public void setReputation (réputation entière) this.reputation = reputation;  public Integer getUserId () return userId;  public void setUserId (Integer userId) this.userId = userId;  public String getUserType () return userType;  public void setUserType (String userType) this.userType = userType;  public String getProfileImage () return profileImage;  public void setProfileImage (String profileImage) this.profileImage = profileImage;  public String getDisplayName () return displayName;  public void setDisplayName (String displayName) this.displayName = displayName;  public String getLink () return link;  public void setLink (lien de chaîne) this.link = link;  public Integer getAcceptRate () return acceptRate;  public void setAcceptRate (Integer acceptRate) this.acceptRate = acceptRate; 

Faire la même chose pour un nouveau Article classe, copie de jsonschema2pojo. 

importer com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; Classe publique Item @SerializedName ("owner") @Expose private Owner owner; @SerializedName ("is_accepted") @Expose private Boolean isAccepted; @SerializedName ("score") @Expose score d'entier privé; @SerializedName ("last_activity_date") @Expose private Integer lastActivityDate; @SerializedName ("creation_date") @Expose private Integer creationDate; @SerializedName ("answer_id") @Expose private Integer answerId; @SerializedName ("question_id") @Expose private Integer questionId; @SerializedName ("last_edit_date") @Expose private Integer lastEditDate; public Owner getOwner () return propriétaire;  public void setOwner (Propriétaire) this.owner = propriétaire;  public Boolean getIsAccepted () return isAccepted;  public void setIsAccepted (booléen est accepté) this.isAccepted = isAccepted;  public Integer getScore () return score;  public void setScore (score entier) this.score = score;  public Integer getLastActivityDate () return lastActivityDate;  public void setLastActivityDate (Integer lastActivityDate) this.lastActivityDate = lastActivityDate;  public Integer getCreationDate () return creationDate;  public void setCreationDate (Integer creationDate) this.creationDate = creationDate;  public Integer getAnswerId () return answerId;  public void setAnswerId (Integer answerId) this.answerId = answerId;  public Integer getQuestionId () return questionId;  public void setQuestionId (Integer questionId) this.questionId = questionId;  public Integer getLastEditDate () return lastEditDate;  public void setLastEditDate (Integer lastEditDate) this.lastEditDate = lastEditDate; 

Enfin, créez une classe nomméeSOAnswersResponse pour les réponses StackOverflow retournées. Vous trouverez le code de cette classe dans jsonschema2pojo en Exemple. Assurez-vous de mettre à jour le nom de la classe sur SOAnswersResponse où qu'il se produise. 

importer com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; importer java.util.List; Classe publique SOAnswersResponse @SerializedName ("items") @Expose Private List items = null; @SerializedName ("has_more") @Expose private Boolean hasMore; @SerializedName ("backoff") @Expose private Integer backoff; @SerializedName ("quota_max") @Expose private Integer quotaMax; @SerializedName ("quota_remaining") @Expose private Integer quotaRemaining; liste publique getItems () renvoie les éléments;  public void setItems (Liste items) this.items = items;  public Boolean getHasMore () return hasMore;  public void setHasMore (Boolean hasMore) this.hasMore = hasMore;  public Integer getBackoff () return backoff;  public void setBackoff (Integer backoff) this.backoff = backoff;  public Integer getQuotaMax () return quotaMax;  public void setQuotaMax (Integer quotaMax) this.quotaMax = quotaMax;  public Integer getQuotaRemaining () return quotaRemaining;  public void setQuotaRemaining (Integer quotaRemaining) this.quotaRemaining = quotaRemaining; 

5. Création de l'instance de modernisation

Pour envoyer des requêtes réseau à une API REST avec Retrofit, nous devons créer une instance à l'aide de la Retrofit.Builder classe et le configurer avec une URL de base. 

Créer un nouveau package de sous-package dans le Les données paquet et nommez-le éloigné. Maintenant à l'intérieur éloigné, créer une classe Java et nommez-la RetrofitClient. Cette classe créera un singleton de Retrofit. Retrofit a besoin d’une URL de base pour construire son instance. Nous allons donc transmettre une URL lors de l’appel. RetrofitClient.getClient (String baseUrl). Cette URL sera ensuite utilisée pour construire l'instance à la ligne 13. Nous spécifions également le convertisseur JSON dont nous avons besoin (Gson) à la ligne 14.. 

import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitClient privé statique Retrofit retrofit = null; public public Retrofit getClient (String baseUrl) if (retrofit == null) retrofit = new Retrofit.Builder () .baseUrl (baseUrl) .addConverterFactory (GsonConverterFactory.create ()) .build ();  retour ultérieur;  

6. Création de l'interface API

Dans le package distant, créez une interface et appelez-la. SOService. Cette interface contient des méthodes que nous allons utiliser pour exécuter des requêtes HTTP telles que OBTENIRPOSTERMETTRE, PIÈCE, et EFFACER. Pour ce tutoriel, nous allons exécuter une OBTENIR demande. 

importer com.chikeandroid.retrofittutorial.data.model.SOAnswersResponse; importer java.util.List; import retrofit2.Call; import retrofit2.http.GET; interface publique SOService @GET ("/ answers? order = desc & sort = activity & site = stackoverflow") Appeler getAnswers (); @GET ("/ answers? Order = desc & sort = activity & site = stackoverflow") Appeler getAnswers (@Query ("tagged") balises de chaîne);  

le @OBTENIR l'annotation définit explicitement cela OBTENIR requête qui sera exécutée une fois la méthode appelée. Chaque méthode de cette interface doit avoir une annotation HTTP qui fournit la méthode de requête et l'URL relative. Cinq annotations intégrées sont disponibles: @OBTENIR@POSTER, @METTRE@EFFACER, et @TÊTE.

Dans la deuxième définition de méthode, nous avons ajouté un paramètre de requête pour filtrer les données du serveur. La rénovation a la @Query ("clé") annotation à utiliser au lieu de la coder en dur dans le noeud final. La valeur de la clé représente le nom du paramètre dans l'URL. Il sera ajouté à l'URL par Retrofit. Par exemple, si on passe la valeur "Android" comme argument à la getAnswers (balises de chaîne) méthode, l'URL complète sera:

https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow&tagged=android

Les paramètres des méthodes d'interface peuvent avoir les annotations suivantes:

@Chemin substitution de variable pour le point de terminaison de l'API
@Question spécifie le nom de la clé de requête avec la valeur du paramètre annoté
@Corps charge utile pour l'appel POST 
@Entête spécifie l'en-tête avec la valeur du paramètre annoté

7. Création des utilitaires API

Nous allons maintenant créer une classe d’utilité. Nous l'appellerons ApiUtils. Cette classe aura l’URL de base en tant que variable statique et fournira également le SOService interface à notre application à travers le getSOService () méthode statique.

Classe publique ApiUtils public static final String BASE_URL = "https://api.stackexchange.com/2.2/"; public statique SOService getSOService () return RetrofitClient.getClient (BASE_URL) .create (SOService.class);  

8. Afficher sur un RecyclerView

Puisque les résultats seront affichés dans une vue du recycleur, nous avons besoin d’un adaptateur. L'extrait de code suivant montre le AnswersAdapter classe.

Classe publique AnswersAdapter étend RecyclerView.Adapter liste privée les éléments; contexte privé mContext; private PostItemListener mItemListener; Classe publique ViewHolder étend RecyclerView.ViewHolder implémente View.OnClickListener public TextView titleTv; PostItemListener mItemListener; public ViewHolder (Voir itemView, PostItemListener postItemListener) super (itemView); titleTv = (TextView) itemView.findViewById (android.R.id.text1); this.mItemListener = postItemListener; itemView.setOnClickListener (this);  @Override public void onClick (vue View) Item item = getItem (getAdapterPosition ()); this.mItemListener.onPostClick (item.getAnswerId ()); notifyDataSetChanged ();  public AnswersAdapter (contexte de contexte, liste posts, PostItemListener itemListener) mItems = posts; mContext = context; mItemListener = itemListener;  @Override public AnswersAdapter.ViewHolder onCreateViewHolder (parent de ViewGroup, int viewType) Contexte de contexte = parent.getContext (); LayoutInflater inflater = LayoutInflater.from (contexte); Voir postView = inflater.inflate (android.R.layout.simple_list_item_1, parent, false); ViewHolder viewHolder = new ViewHolder (postView, this.mItemListener); retourne viewHolder;  @Override public void onBindViewHolder (titulaire de AnswersAdapter.ViewHolder, position int) Item item = mItems.get (position); TextView textView = holder.titleTv; textView.setText (item.getOwner (). getDisplayName ());  @Override public int getItemCount () return mItems.size ();  public void updateAnswers (Liste items) mItems = items; notifyDataSetChanged ();  élément privé getItem (int adapterPosition) return mItems.get (adapterPosition);  interface publique PostItemListener void onPostClick (id long); 

9. Exécuter la demande

À l'intérieur de onCreate () méthode du Activité principale, nous initialisons une instance du SOService interface (ligne 9), la vue recycleur, ainsi que l'adaptateur. Enfin, nous appelons le loadAnswers () méthode. 

 private AnswersAdapter mAdapter; RecyclerView privé mRecyclerView; SOService privé mService; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); mService = ApiUtils.getSOService (); mRecyclerView = (RecyclerView) findViewById (R.id.rv_answers); mAdapter = new AnswersAdapter (this, nouvel ArrayList(0), new AnswersAdapter.PostItemListener () @Override public void onPostClick (id long) Toast.makeText (MainActivity.this, "ID post est" + id, Toast.LENGTH_SHORT) .show (); ); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager (this); mRecyclerView.setLayoutManager (layoutManager); mRecyclerView.setAdapter (mAdapter); mRecyclerView.setHasFixedSize (true); RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration (this, DividerItemDecoration.VERTICAL_LIST); mRecyclerView.addItemDecoration (itemDecoration); loadAnswers (); 

le loadAnswers () méthode effectue une requête réseau en appelant enqueue (). Lorsque la réponse est renvoyée, Retrofit nous aide à analyser la réponse JSON dans une liste d'objets Java. (Ceci est rendu possible en utilisant GsonConverter.)  

public void loadAnswers () mService.getAnswers (). en file d'attente (nouveau rappel() @Override public void onResponse (Call appel, réponse réponse) if (response.isSuccessful ()) mAdapter.updateAnswers (response.body (). getItems ()); Log.d ("MainActivity", "publications chargées à partir de l'API");  else int statusCode = response.code (); // traite les erreurs de requête en fonction du code d'état @Override public void onFailure (Call appel, Throwable t) showErrorMessage (); Log.d ("MainActivity", "erreur lors du chargement à partir de l'API"); ); 

10. 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. Cette demande étant asynchrone, Retrofit la gère sur un thread d'arrière-plan afin que le thread d'interface utilisateur principal ne soit ni bloqué ni perturbé..

Utiliser enqueue (), vous devez implémenter deux méthodes de rappel:

  • onResponse ()
  • 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. 

Pour effectuer une requête synchrone, vous pouvez utiliser le exécuter() méthode. Sachez 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 cela, exécutez-les sur un thread d'arrière-plan.

11. Test de l'application

Vous pouvez maintenant lancer l'application. 

12. Intégration RxJava

Si vous êtes un fan de RxJava, vous pouvez facilement implémenter Retrofit avec RxJava. Dans Retrofit 1, il était intégré par défaut, 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

É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 création d'une instance de modification.  

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

Maintenant, mettez à jour le getAnswers ()  méthodes pour retourner Observables:

@GET ("/ answers? Order = desc & sort = activity & site = stackoverflow") Observable getAnswers (); @GET ("/ answers? Order = desc & sort = activity & site = stackoverflow") Observable getAnswers (@Query ("tagged") balises String); 

Étape 4

Lors de la demande, notre abonné anonyme répond au flux de l'observable qui émet des événements, dans notre cas SOAnswersResponse. le onNext La méthode est ensuite appelée lorsque notre abonné reçoit tout événement émis qui est ensuite transmis à notre adaptateur.. 

@Override public void loadAnswers () mService.getAnswers (). SubscribeOn (Schedulers.io ()). ObserveOn (AndroidSchedulers.mainThread ()) .subscribe (nouvel abonné() @Override public nul onCompleted ()  @Override public vide onError (Throwable e)  @Override public nul onNext (SOAnswersResponse soAnswersResponse) mAdapter.updateAnswers (soAnswersResponse.getItems ()); ); 

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

Conclusion

Dans ce didacticiel, vous avez découvert Retrofit: pourquoi et comment l’utiliser. J'ai aussi expliqué comment ajouter l'intégration de RxJava à Retrofit. Dans mon prochain post, je vais vous montrer comment jouer POSTERMETTRE, et EFFACER, comment envoyer Form-Urlencoded données, et comment annuler les demandes. 

Pour en savoir plus sur Retrofit, reportez-vous à la documentation officielle. Et en attendant, découvrez certains de nos autres cours et tutoriels sur le développement d'applications Android..

  • Communication au sein d'une application Android avec EventBus

    Greenrobot EventBus est une bibliothèque open source populaire qui utilise le modèle de publication / abonnement pour la communication entre les composants du système Android. Dans…
    Chike Mgbemena
    Android
  • 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
  • Android From Scratch: Utilisation des API REST

    Dans ce tutoriel, je vais vous montrer comment utiliser les classes et les méthodes disponibles dans le SDK Android pour vous connecter à des serveurs Web distants et interagir avec…
    Ashraff Hathibelagal
    SDK Android
  • Commencer avec un modèle d'application Android en 60 secondes

    CodeCanyon propose des centaines de modèles d'applications Android que vous pouvez utiliser pour lancer votre développement. Cette vidéo vous montrera comment installer et personnaliser…
    Ashraff Hathibelagal
    SDK Android