Gegevens verzenden met Retrofit 2 HTTP Client voor Android

Wat je gaat creëren

Wat is retrofit?

Retrofit is een typevaste HTTP-client voor Android en Java. Retrofit maakt het eenvoudig om verbinding te maken met een REST-webservice door de API te vertalen naar Java-interfaces. In deze zelfstudie laat ik u zien hoe u een van de populairste en vaak aanbevolen HTTP-bibliotheken gebruikt die beschikbaar zijn voor Android.

Deze krachtige bibliotheek maakt het gemakkelijk om JSON- of XML-gegevens te verbruiken, die vervolgens worden geparseerd in Plain Old Java Objects (POJOs). KRIJGENPOSTLEGGENPATCH, en DELETE aanvragen kunnen allemaal worden uitgevoerd. 

Net als de meeste open-source software, is Retrofit gebouwd op een aantal andere krachtige bibliotheken en hulpmiddelen. Achter de schermen maakt Retrofit gebruik van OkHttp (van dezelfde ontwikkelaar) om netwerkverzoeken af ​​te handelen. Retrofit heeft ook geen ingebouwde JSON-converter om te analyseren van JSON naar Java-objecten. In plaats daarvan wordt de ondersteuning voor de volgende JSON-converterbibliotheken ondersteund om dat probleem aan te pakken:

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

Voor protocolbuffers ondersteunt Retrofit:

  • Protobuf: com.squareup.retrofit2:-converter protobuf
  • Draad: com.squareup.retrofit2: converter-wire

En voor XML Retrofit ondersteunt:

  • Eenvoudig kader: com.squareup.retrofit2:-converter simpleframework

Dus waarom gebruik retrofit?

Het ontwikkelen van uw eigen typevaste HTTP-bibliotheek voor interface met een REST-API kan heel lastig zijn: u moet veel aspecten behandelen, zoals verbindingen maken, caching, mislukte aanvragen opnieuw proberen, threading, parsering van reacties, foutafhandeling en meer. Retrofit, aan de andere kant, is een goed geplande, gedocumenteerde en geteste bibliotheek die u veel kostbare tijd en hoofdpijn bespaart.

In deze tutorial leg ik uit hoe u Retrofit 2 kunt gebruiken om netwerkverzoeken af ​​te handelen door een eenvoudige app te bouwen die zal presteren POST verzoeken, LEGGEN verzoeken (om entiteiten bij te werken), en DELETE verzoeken. Ik zal je ook laten zien hoe je kunt integreren met RxJava en hoe je aanvragen kunt annuleren. We zullen de door JSONPlaceholder geleverde API gebruiken - dit is een nep-online REST-API voor testen en prototypen.

Bekijk mijn vorige bericht, Aan de slag met Retrofit 2 HTTP Client, om te leren hoe u kunt uitvoeren KRIJGEN aanvragen en hoe Retrofit met RxJava te integreren. 

1. Maak een Android Studio-project

Start Android Studio en maak een nieuw project met een lege activiteit genaamd Hoofdactiviteit.

2. Afhankelijkheden declareren

Nadat u een nieuw project hebt gemaakt, declareert u de volgende afhankelijkheden in uw build.gradle. De afhankelijkheden omvatten de Retrofit-bibliotheek en ook Google's Gson-bibliotheek om JSON naar POJO (Plain Old Java Objects) en Retrofit's Gson-integratie om te zetten. 

// Retrofit compile 'com.squareup.retrofit2: retrofit: 2.1.0' // JSON Parsing compileer 'com.google.code.gson: gson: 2.6.1' compile 'com.squareup.retrofit2: converter-gson: 2.1 0,0'

Zorg ervoor dat je je project synchroniseert nadat je de afhankelijkheden hebt toegevoegd. 

3. Internettoestemming toevoegen

Om netwerkbewerkingen uit te voeren, moeten we de INTERNET toestemming in het toepassingsmanifest: AndroidManifest.xml.

           

4. Modellen automatisch genereren

We gaan automatisch modellen maken van de JSON-responsgegevens door gebruik te maken van een zeer nuttige tool: jsonschema2pojo. We willen graag een maken POST aanvraag (maak een nieuwe bron) op de API. Maar voordat we dit verzoek uitvoeren, moeten we de JSON-reactie kennen die we zouden moeten verwachten als het met succes wordt uitgevoerd, zodat Retrofit de JSON-reactie kan analyseren en deserialiseren naar Java-objecten. Volgens de API, als we de volgende gegevens in een POST verzoek:

data: title: 'foo', body: 'bar', userId: 1

We zouden het volgende antwoord moeten krijgen:

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

Wijs de JSON-gegevens toe aan Java 

Kopieer de voorbeeldantwoordgegevens uit het vorige gedeelte. Ga nu naar jsonschema2pojo en plak de JSON-reactie in het invoervak. Selecteer het brontype van JSON, annotatiestijl van Gson, haal het vinkje weg Sta extra eigenschappen toe, en verander de klassennaam van Voorbeeld naar Post

Klik vervolgens op de Voorbeeld om de Java-objecten te genereren. 

Je vraagt ​​je misschien af ​​wat de @SerializedName en @Expose annotaties doen in deze gegenereerde code! Maak je geen zorgen, ik zal het allemaal uitleggen!

De @SerializedName annotatie is nodig voor Gson om de JSON-sleutels toe te wijzen aan Java-objectvelden.

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

In dit geval de JSON-sleutel gebruikersnaam is toegewezen aan het klassenveld gebruikersnaam. Maar let op: aangezien ze hetzelfde zijn, is het niet nodig om de @SerializedName annotatie op het veld, omdat Gson het automatisch voor ons in kaart brengt.

De @Expose annotatie geeft aan dat het klaslid moet worden blootgesteld voor JSON-serialisatie of deserialisatie. 

Gegevensmodellen importeren in Android Studio

Laten we nu teruggaan naar Android Studio. Maak een nieuw subpakket in de hoofd pakket en noem het gegevens. Maak binnen het nieuw gemaakte pakket een nieuw pakket en geef het een naam model-. Binnen dit pakket maakt u een nieuwe Java-klasse en geeft u deze een naam Post. Kopieer nu het Post klasse die is gegenereerd door jsonschema2pojo en plak deze in de Post klas die je hebt gemaakt. 

pakket com.chikeandroid.retrofittutorial2.data.model; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; public class-bericht @SerializedName ("title") @Expose private String-titel; @SerializedName ("body") @Expose private String body; @SerializedName ("userId") @Expose private Integer userId; @SerializedName ("id") @Expose private Integer id; public String getTitle () return title;  public void setTitle (String title) this.title = title;  public String getBody () body terughalen;  public void setBody (String body) 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 gesprek savePost (@Field ("title") String title, @Field ("body") String body, @Field ("userId") lange userId); 

Kijken naar de APIService klasse, we hebben een methode genaamd savePost (). Bovenop de methode staat de @POST annotatie, wat aangeeft dat we a willen uitvoeren POST aanvraag wanneer deze methode wordt aangeroepen. De argumentwaarde voor de @POST annotatie is het eindpunt - wat is / berichten. Dus de volledige URL is http://jsonplaceholder.typicode.com/posts. 

Oké, dus hoe zit het met de @FormUrlEncoded? Dit geeft aan dat het verzoek het MIME-type zal hebben (een kopveld dat de indeling van het hoofdgedeelte van een HTTP-verzoek of reactie aangeeft) ingesteld op application / x-www-form-urlencoded en ook dat de veldnamen en -waarden UTF-8-gecodeerd zijn voordat ze URI-gecodeerd zijn. De @Field ( "key") annotatie met parameternaam moet overeenkomen met de naam die de API verwacht. Retrofit converteert impliciet de waarden naar tekenreeksen met String.valueOf (Object), en de strings worden dan URL-gecodeerd. nul waarden worden genegeerd. 

Bijvoorbeeld bellen APIService.savePost ("Mijn bezoek aan Lagos", "Ik bezocht ...", 2) levert een request body op van title = My + Visit + To + Lagos & body = I + visited ... & userId = 2.

De ... gebruiken @Lichaam aantekening

We kunnen ook de @Lichaam annotatie op een servicemethode-parameter in plaats van het opgeven van een formulier-achtige aanvraag-instantie met een aantal afzonderlijke velden. Het object wordt geserialiseerd met behulp van de retrofit aanleg omvormer opgegeven tijdens het maken. Dit wordt alleen gebruikt bij het uitvoeren van een van beide POST of LEGGEN operatie. 

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

7. De API-hulpprogramma's maken

We gaan een utility-klasse maken. Dus maak een les in data.remote en noem het ApiUtils. Deze klasse heeft de basis-URL als een statische variabele en biedt ook de APIService interface door met een getAPIService () statische methode voor de rest van onze applicatie.

pakket com.chikeandroid.retrofittutorial2.data.remote; public class ApiUtils private ApiUtils ()  public static final String BASE_URL = "http://jsonplaceholder.typicode.com/"; openbare statische APIService getAPIService () retourneer RetrofitClient.getClient (BASE_URL) .create (APIService.class); 

Zorg ervoor dat u de basis-URL beëindigt met een /

8. De lay-out maken

Het bestand activity_main.xml is de lay-out voor onze Hoofdactiviteit. Deze lay-out heeft één tekstbewerkingsveld voor de titel van het bericht en een ander voor de hoofdtekst van het bericht. Het bevat ook een knop om het bericht in te dienen bij de API. 

     

9. De POST-aanvraag uitvoeren

In de onCreate () methode in Hoofdactiviteit, we initialiseren een instantie van de APIService interface (regel 14). We initialiseren ook de Tekst bewerken velden en een verzendknop die de sendPost () methode wanneer erop wordt geklikt (regel 22).

private TextView mResponseTv; private APIService mAPIService; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); laatste EditText titleEt = (EditText) findViewById (R.id.et_title); final EditText bodyEt = (EditText) findViewById (R.id.et_body); Knop submitBtn = (Button) findViewById (R.id.btn_submit); mResponseTv = (TextView) findViewById (R.id.tv_response); mAPIService = ApiUtils.getAPIService (); submitBtn.setOnClickListener (new View.OnClickListener () @Override public void onClick (View view) String title = titleEt.getText (). toString (). trim (); String body = bodyEt.getText (). toString () .trim (); if (! TextUtils.isEmpty (title) &&! TextUtils.isEmpty (body)) sendPost (title, body);); 

In de sendPost (String, String) methode in de Hoofdactiviteit klasse, hebben we de titel en tekst van de post doorgegeven aan deze methode. Wat deze methode zal doen, is onze API Service Interface-methode aanroepen savePost (String, String) wiens taak het is om een POST verzoek om de titel en body naar de API te sturen. De showResponse (String-reactie) methode geeft het antwoord op het scherm weer.

public void sendPost (String title, String body) mAPIService.savePost (title, body, 1) .enqueue (new Callback() @Override public void onResponse (Call oproep, antwoord antwoord) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "post ingediend bij API." + Response.body (). ToString ());  @Override openbare ongeldig onFailure (Oproep call, Throwable t) Log.e (TAG, "Kan bericht niet verzenden naar API."); );  public void showResponse (String response) if (mResponseTv.getVisibility () == View.GONE) mResponseTv.setVisibility (View.VISIBLE);  mResponseTv.setText (antwoord); 

Onze APIService aanleg mAPIService methode savePost (String, String) zal terugkeren a telefoontje instantie die een methode heeft genaamd enqueue (Callback Bel terug).

Begrip enqueue ()

enqueue () verzendt asynchroon het verzoek en stelt uw app op de hoogte met een terugroep wanneer een reactie terugkomt. Aangezien dit verzoek asynchroon is, verwerkt Retrofit de uitvoering op een achtergrondthread, zodat de hoofd UI-thread niet wordt geblokkeerd of geïnterfereerd. 

Om de te gebruiken enqueue () methode, moet u twee callback-methoden implementeren: onResponse () en onFailure (). Slechts één van deze methoden zal worden gebruikt als antwoord op een gegeven verzoek. 

  • onResponse (): aangeroepen voor een ontvangen HTTP-reactie. Deze methode vraagt ​​om een ​​antwoord dat correct kan worden afgehandeld, zelfs als de server een foutmelding geeft. Dus als u een statuscode van 404 of 500 krijgt, wordt deze methode nog steeds gebeld. Om de statuscode op volgorde te krijgen zodat u de situaties op basis daarvan kunt afhandelen, kunt u de methode gebruiken Reactiecode(). U kunt ook de is succesvol() methode om te achterhalen of de statuscode binnen het bereik 200-300 ligt, met vermelding van succes.
  • onFailure (): wordt aangeroepen wanneer een netwerkuitzondering optreedt die communiceert met de server of wanneer er een onverwachte uitzondering is opgetreden bij het verwerken van het verzoek of het verwerken van het antwoord.

Synchrone verzoeken

Als u een synchrone aanvraag wilt uitvoeren, gebruikt u de execute () methode in a telefoontje aanleg. Houd er echter rekening mee dat synchrone methoden op de hoofd- / UI-thread elke actie van een gebruiker blokkeren. Dus voer geen synchrone methoden uit op de hoofd- / UI-thread van Android! Voer ze in plaats daarvan uit op een achtergrondthread.

RxJava gebruiken 

RxJava is standaard in Retrofit 1 geïntegreerd, maar in Retrofit 2 moet u enkele extra afhankelijkheden opnemen. Retrofit wordt geleverd met een standaard-adapter voor uitvoering telefoontje instances. U kunt dus het uitvoeringsmechanisme van Retrofit wijzigen om RxJava op te nemen door de RxJava op te nemen CallAdapter. Dit zijn de stappen:

Stap 1

Voeg de afhankelijkheden toe.

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

Stap 2

Voeg de nieuwe CallAdapter toe RxJavaCallAdapterFactory.create () bij het bouwen van een Retrofit-instantie (regel 5).  

public static Retrofit getClient (String baseUrl) if (retrofit == null) retrofit = new Retrofit.Builder () .baseUrl (baseUrl) .addCallAdapterFactory (RxJavaCallAdapterFactory.create ()) .addConverterFactory (GsonConverterFactory.create ()) .build ();  retrofit retourneren; 

Stap 3

Werk het APIService savePost (String title, String body, String userId) methode om waarneembaar te worden. 

@POST ("/ posts") @FormUrl gecodeerd waarneembaar savePost (@Field ("title") String title, @Field ("body") String body, @Field ("userId") lange userId);

Stap 4

Bij het indienen van de verzoeken reageert onze anonieme abonnee op de stream van de observeerbare waar in ons geval gebeurtenissen worden uitgezonden Post. De onNext methode wordt dan aangeroepen wanneer onze abonnee een evenement ontvangt, dat vervolgens wordt doorgegeven aan ons showResponse (String-reactie) methode. 

public void sendPost (String title, String body) // RxJava mAPIService.savePost (title, body, 1) .subscribeOn (Schedulers.io ()). observedOn (AndroidSchedulers.mainThread ()) .subscribe (nieuwe abonnee() @Override public void onCompleted ()  @Override public void onError (Throwable e)  @Override public void onNext (Post post) showResponse (post.toString ()); ); 

Bekijk Aan de slag met ReactiveX op Android door Ashraff Hathibelagal voor meer informatie over RxJava en RxAndroid. 

10. De app testen

Op dit punt kunt u de app uitvoeren en op de knop Verzenden klikken wanneer u een titel en tekst hebt ingevoerd. Het antwoord van de API wordt weergegeven onder de knop Verzenden. 

11. Een PUT-verzoek uitvoeren

Nu we weten hoe we een moeten uitvoeren POST verzoek, laten we zien hoe we een kunnen uitvoeren LEGGEN aanvraag die entiteiten bijwerkt. Voeg de volgende nieuwe methode toe aan de APIService klasse. 

@PUT ("/ posts / id") @FormUrlEncoded gesprek updatePost (@Path ("id") lange id, @Field ("titel") Stringtitel, @Field ("body") String body, @Field ("userId") lange userId);

Om een ​​bericht vanuit de API bij te werken, hebben we het eindpunt / Berichten / id met ID kaart een plaatshouder zijn voor de id van de post die we willen updaten. De @Pad annotatie is de naamvervanging in een URL-padsegment ID kaart. Houd er rekening mee dat waarden worden omgezet in string met String.valueOf (Object) en URL gecodeerd. Als de waarde al is gecodeerd, kunt u URL-codering als volgt uitschakelen: @Path (value = "name", encoded = true)

12. Uitvoeren van een DELETE-verzoek

Laten we ook zien hoe een a uit te voeren DELETE verzoek. Met behulp van de JSONPlaceholder API is het vereiste eindpunt om een ​​postresource te verwijderen / Berichten / id met de HTTP-methode DELETE. Terug naar onze APIService interface, we moeten alleen de methode opnemen Verwijder gepost bericht() die het zal uitvoeren. We geven de id van de post door aan de methode en deze wordt vervangen in het segment URL-pad ID kaart.

@DELETE ("/ posts / id") Bellen deletePost (@Path ("id") lange id);

13. Een aanvraag annuleren

Stel dat u uw gebruikers de mogelijkheid wilt geven om een ​​aanvraag te annuleren of af te breken. Dit is heel eenvoudig in Retrofit. De retrofit telefoontje klasse heeft een methode genaamd annuleren() dat zal precies dat doen (regel 32 hieronder). Deze methode activeert de onFailure () methode in de callback. 

Deze methode kan bijvoorbeeld worden aangeroepen als er geen internetverbinding is of als er een onverwachte uitzondering is opgetreden bij het maken van het verzoek of bij het verwerken van het antwoord. Om te weten of het verzoek is geannuleerd, gebruikt u de methode is geannuleerd() in de telefoontje klasse (regel 20). 

privé gesprek mCall; ... public sendPost (String-titel, String-body) mCall = mAPIService.savePost (titel, hoofdtekst, 1); mCall.enqueue (nieuwe terugbelopdracht() @Override public void onResponse (Call oproep, antwoord antwoord) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "post ingediend bij API." + Response.body (). ToString ());  @Override openbare ongeldig onFailure (Oproep call, Throwable t) if (call.isCanceled ()) Log.e (TAG, "request was aborted");  else Log.e (TAG, "Kan bericht niet verzenden naar API.");  showErrorMessage (); );  public void cancelRequest () mCall.cancel (); 

Conclusie

In deze tutorial hebt u geleerd over Retrofit: waarom zou u het moeten gebruiken en hoe u het in uw project kunt integreren om uit te voeren POSTLEGGENDELETE en annuleer verzoeken. Je hebt ook geleerd hoe je RxJava ermee kunt integreren. In mijn volgende bericht over het gebruik van Retrofit laat ik je zien hoe je bestanden kunt uploaden. 

Raadpleeg de officiële documentatie voor meer informatie over Retrofit. En bekijk hier enkele van onze andere tutorials en cursussen over Android-ontwikkeling bij Envato Tuts+!

  • Animate Your Android App

    Animaties zijn een belangrijk onderdeel van de Android-gebruikerservaring geworden. Subtiele, goed gemaakte animaties worden overal in het Android-besturingssysteem gebruikt en kunnen uw ...
    Ashraff Hathibelagal
    Mobiele ontwikkeling
  • Praktische concurrency op Android met HaMeR

    In deze tutorial verkennen we het HaMeR-framework (Handler, Message en Runnable), een van de krachtigste concurrency-modellen die beschikbaar zijn op Android. Met een…
    Tin Megali
    Android SDK
  • Codering Functionele Android-apps in Kotlin: Aan de slag

    Heb je positieve dingen gehoord over de Kotlin-taal voor Android-apps en wil je het zelf proberen? Ontdek hoe u de codering in deze nieuwe ...
    Jessica Thornsby
    Android Studio
  • Migreer een Android-app naar Material Design

    Jaren geleden, toen Android nog een ontluikend mobiel besturingssysteem was, was het nogal berucht om zijn lelijke gebruikersinterface. Omdat er geen ontwerp was ...
    Ashraff Hathibelagal
    Android