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). KRIJGEN
, POST
, LEGGEN
, PATCH
, 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:
com.squareup.retrofit:-converter gson
com.squareup.retrofit: converter-jackson
com.squareup.retrofit:-converter moshi
Voor protocolbuffers ondersteunt Retrofit:
com.squareup.retrofit2:-converter protobuf
com.squareup.retrofit2: converter-wire
En voor XML Retrofit ondersteunt:
com.squareup.retrofit2:-converter simpleframework
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.
Start Android Studio en maak een nieuw project met een lege activiteit genaamd Hoofdactiviteit
.
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.
Om netwerkbewerkingen uit te voeren, moeten we de INTERNET
toestemming in het toepassingsmanifest: AndroidManifest.xml.
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.
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 gespreksavePost (@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
.
@Lichaam
aantekeningWe 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 gespreksavePost (@Body Post bericht);
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 /
.
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.
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
.
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.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 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:
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'
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;
Werk het APIService
savePost (String title, String body, String userId)
methode om waarneembaar te worden.
@POST ("/ posts") @FormUrl gecodeerd waarneembaarsavePost (@Field ("title") String title, @Field ("body") String body, @Field ("userId") lange userId);
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.
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.
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 gesprekupdatePost (@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)
.
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") BellendeletePost (@Path ("id") lange id);
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é gesprekmCall; ... 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 ();
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 POST
, LEGGEN
, DELETE
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+!