Retrofit er en type sikker HTTP-klient for Android og Java. Retrofit gjør det enkelt å koble til en REST webtjeneste ved å oversette API-en til Java-grensesnitt. I denne veiledningen viser jeg deg hvordan du bruker et av de mest populære og ofte anbefalte HTTP-bibliotekene som er tilgjengelige for Android.
Dette kraftige biblioteket gjør det enkelt å konsumere JSON- eller XML-data, som deretter blir analysert i Vanlige gamle Java-objekter (POJOs). FÅ
, POST
, SETTE
, LAPP
, og SLETT
forespørsler kan alle bli utført.
Som de fleste open source-programvare ble Retrofit bygget på toppen av noen andre kraftige biblioteker og verktøy. Bak kulissene bruker Retrofit OkHttp (fra samme utvikler) til å håndtere nettverksforespørsler. Retrofit har heller ikke en innebygd JSON-omformer for å analysere fra JSON til Java-objekter. I stedet sender den støtte til følgende JSON-konverteringsbiblioteker for å håndtere det:
com.squareup.retrofit: converter-gson
com.squareup.retrofit: converter-jackson
com.squareup.retrofit: converter-moshi
For protokollbuffere støtter Retrofit:
com.squareup.retrofit2: converter-Protobuf
com.squareup.retrofit2: konverter-ledning
Og for XML Retrofit, støtter:
com.squareup.retrofit2: converter-simpleframework
Å utvikle ditt eget type-sikre HTTP-bibliotek til grensesnitt med en REST-API kan være en reell smerte: du må håndtere mange aspekter, for eksempel å lage tilkoblinger, cache, forsøke mislykkede forespørsler, tråder, responsanalyse, feilhåndtering og mer. Retrofit, derimot, er et godt planlagt, dokumentert og testet bibliotek som vil spare deg for mye dyrebar tid og hodepine.
I denne veiledningen vil jeg forklare hvordan du bruker Retrofit 2 til å håndtere nettverksforespørsler ved å bygge en enkel app som skal utføre POST
forespørsler, SETTE
forespørsler (for å oppdatere enheter), og SLETT
forespørsler. Jeg vil også vise deg hvordan du integrerer med RxJava og hvordan du kansellerer forespørsler. Vi bruker APIen levert av JSONPlaceholder-dette er en falsk online REST API for testing og prototyping.
Sjekk ut mitt forrige innlegg, Kom i gang med Retrofit 2 HTTP-klient, for å lære å utføre FÅ
forespørsler og hvordan å integrere Retrofit med RxJava.
Brann opp Android Studio og opprett et nytt prosjekt med en tom aktivitet som heter Hoved aktivitet
.
Når du har opprettet et nytt prosjekt, erklærer du følgende avhengigheter i din build.gradle
. Avhengighetene inkluderer Retrofit-biblioteket og også Googles Gson-bibliotek for å konvertere JSON til POJO (Plain Old Java Objects) samt Retrofits Gson-integrasjon.
// Retrofit compile 'com.squareup.retrofit2: retrofit: 2.1.0' // JSON Parsing compile 'com.google.code.gson: gson: 2.6.1' compile 'com.squareup.retrofit2: converter-gson: 2.1 0,0'
Pass på at du synkroniserer prosjektet ditt etter å ha lagt til avhengighetene.
For å utføre nettverksoperasjoner må vi inkludere INTERNETT
Tillatelse i søknadsmanifestet: AndroidManifest.xml.
Vi skal lage modeller automatisk fra JSON-responsdataene ved å utnytte et veldig nyttig verktøy: jsonschema2pojo. Vi ønsker å lage en POST
forespørsel (opprett en ny ressurs) på APIen. Men før vi utfører denne forespørselen, trenger vi å vite JSON-responsen vi bør forvente når den utføres, slik at Retrofit kan analysere JSON-responsen og deserialisere den til Java-objekter. Ifølge API, hvis vi sender følgende data i en POST
be om:
data: title: 'foo', body: 'bar', userId: 1
Vi bør få følgende svar:
"title": "foo", "body": "bar", "userId": 1, "id": 101
Kart JSON Data til Java
Kopier prøveresponsdataene fra foregående avsnitt. Nå besøker jsonschema2pojo og lim inn JSON-responsen i innskuffen. Velg kilde type av JSON, annoteringsstil av Gson, uncheck Tillat flere egenskaper, og endre klassenavnet fra Eksempel til Post.
Klikk deretter på Forhåndsvisning knappen for å generere Java-objektene.
Du lurer kanskje på hva @SerializedName
og @Avdekke
merknader gjør i denne genererte koden! Ikke bekymre deg, jeg forklarer alt!
De @SerializedName
Merknad er nødvendig for Gson å kartlegge JSON-nøklene til Java-objektfeltene.
@SerializedName ("userId") @Viser privat integer brukerId;
I dette tilfellet er JSON-nøkkelen bruker-ID
er kartlagt til klassefeltet bruker-ID
. Men vær oppmerksom på at siden de er de samme, er det ikke nødvendig å inkludere @SerializedName
annotasjon på feltet fordi Gson vil kartlegge det automatisk for oss.
De @Avdekke
annotasjon indikerer at klassemedlemmet skal bli utsatt for JSON serialisering eller deserialisering.
La oss nå gå tilbake til Android Studio. Lag en ny delpakke inne i hoved-
pakke og navn den data
. Inne i den nyopprettede pakken, opprett en annen pakke og navnet den modell
. Inne i denne pakken lager du en ny Java-klasse og heter den Post
. Kopier nå Post
klassen som ble generert av jsonschema2pojo og lim den inn i Post
klasse du opprettet.
pakke com.chikeandroid.retrofittutorial2.data.model; importer com.google.gson.annotations.Expose; importer com.google.gson.annotations.SerializedName; post i offentlig klasse @SerializedName ("title") @Visstilt privat stringtittel; @SerializedName ("body") @Verstilt privat String body; @SerializedName ("userId") @Viser privat integer brukerId; @SerializedName ("id") @Verlegg privat integer-ID; offentlig String getTitle () retur tittel; Offentlig tomgang setTitle (Stringtittel) this.title = title; offentlig String getBody () return body; Offentlig tomgang setBody (String body) this.body = body; offentlig integer getUserId () return userId; Offentlig tomgang setUserId (Integer userId) this.userId = userId; offentlig integer getId () return id; Offentlig tomgang setId (Integer ID) this.id = id; @Override public String toString () return "Post " + "title = '" + tittel +' \ "+", + body + "\" + ", userId =" + userId + ", / posts") @FormUrlEncoded CallsavePost (@Field ("title") Stringtittel, @Field ("body") String body, @Field ("userId") long userId);
Ser på APIService
klasse, vi har en metode kalt lagre post()
. På toppen av metoden er @POST
annotasjon, som indikerer at vi vil utføre en POST
Be om når denne metoden kalles. Argumentverdien for @POST
annotering er sluttpunktet som er / innlegg
. Så hele nettadressen vil være http://jsonplaceholder.typicode.com/posts.
Ok, så hva med @FormUrlEncoded
? Dette vil indikere at forespørselen vil ha sin MIME-type (et overskriftsfelt som identifiserer formatet til kroppen av en HTTP-forespørsel eller respons) satt til application / x-www-skjema-urlencoded
og også at feltnavnene og verdiene er UTF-8 kodet før de blir URI-kodet. De @Field ( "nøkkel")
annotering med parameternavn skal matche navnet som API forventer. Retrofit konverterer implisitt verdiene til strengene ved hjelp av String.valueOf (objekt)
, og strengene danner deretter URL-kodet. null
verdiene ignoreres.
For eksempel ringer APIService.savePost ("Mitt besøk til Lagos", "Jeg besøkte ...", 2)
gir en forespørsel kropp av title = Min + Besøk + Til + Lagos & body = I + besøkt ... & userId = 2
.
@Kropp
merknadVi kan også bruke @Kropp
annotering på en servicemetodeparameter i stedet for å angi en formular-forespørselslegem med en rekke individuelle felter. Objektet vil bli serialisert ved hjelp av retrofit
forekomst Converter
spesifisert under opprettelsen. Dette brukes kun når du utfører enten a POST
eller SETTE
operasjon.
@POST ("/ innlegg") @FormUrlEncoded CallsavePost (@Body Post innlegg);
Vi skal lage en verktøysklasse. Så skape en klasse i data.remote
og nev det ApiUtils
. Denne klassen vil ha basen URL som en statisk variabel og vil også gi APIService
grensesnitt med med a getAPIService ()
statisk metode til resten av søknaden vår.
pakke com.chikeandroid.retrofittutorial2.data.remote; offentlig klasse ApiUtils privat ApiUtils () offentlig statisk endelig streng BASE_URL = "http://jsonplaceholder.typicode.com/"; offentlig statisk APIService getAPIService () returner RetrofitClient.getClient (BASE_URL) .create (APIService.class);
Pass på at du avslutter basisadressen med en /
.
Filen activity_main.xml er oppsettet for vår Hoved aktivitet
. Denne oppsettet vil ha ett tekstredigeringsfelt for tittelen på innlegget og en annen for postens kropp. Den inneholder også en knapp for å sende innlegget til API.
I onCreate ()
metode i Hoved aktivitet
, vi initialiserer en forekomst av APIService
grensesnitt (linje 14). Vi initialiserer også EditText
felt og en send-knapp som vil ringe til sendPost ()
metode når du klikker (linje 22).
privat tekstvisning mResponseTv; privat APIService mAPIService; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); Endelig EditText titleEt = (EditText) findViewById (R.id.et_title); Endelig EditText bodyEt = (EditText) findViewById (R.id.et_body); Button 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 (Vis visning) String title = titleEt.getText (). toString (). trim (); String body = bodyEt.getText (). toString () .trim (); if (! TextUtils.isEmpty (title) &&! TextUtils.isEmpty (body)) sendPost (tittel, kropp););
I sendPost (streng, streng)
metode i Hoved aktivitet
klasse, vi passerte i tittel og kropp av innlegget til denne metoden. Hva denne metoden vil gjøre, er å ringe til API-tjenestegrensesnittmetoden savePost (String, String)
hvis jobb er å utføre en POST
Be om å sende tittelen og kroppen til API-en. De showResponse (strengrespons)
Metoden vil vise svaret på skjermen.
Offentlig tomt sendPost (Stringtittel, Stringlegeme) mAPIService.savePost (tittel, kropp, 1) .enqueue (ny tilbakeringing() @Overgå offentlig ugyldig påmelding (Ring ring, svar svar) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "post sendt til API." + Response.body (). ToString ()); @Override public void onFailure (Ring Ring, Kastbar t) Log.e (TAG, "Kan ikke sende innlegg til API."); ); offentlig ugyldig showResponse (strengrespons) if (mResponseTv.getVisibility () == View.GONE) mResponseTv.setVisibility (View.VISIBLE); mResponseTv.setText (respons);
Våre APIService
forekomst mAPIService
metode savePost (String, String)
vil returnere a Anrop
eksempel som har en metode kalt Enqueue (Callback
.
Enqueue ()
Enqueue ()
Asynkront sender forespørselen og gir beskjed om appen din med tilbakeringing når et svar kommer tilbake. Siden denne forespørselen er asynkron, håndterer Retrofit utførelsen på en bakgrunnstråd, slik at hovedbruddstråden ikke er blokkert eller forstyrret med.
For å bruke Enqueue ()
metode, må du implementere to tilbakekallingsmetoder: onResponse ()
og onFailure ()
. Bare en av disse metodene vil bli kalt som svar på en gitt forespørsel.
onResponse ()
: Påkrevd for mottatt HTTP-respons. Denne metoden kalles for et svar som kan håndteres på riktig måte, selv om serveren returnerer en feilmelding. Så hvis du får en statuskode på 404 eller 500, vil denne metoden fortsatt bli kalt. For å få statuskoden slik at du kan håndtere situasjoner basert på dem, kan du bruke metoden response.code ()
. Du kan også bruke isSuccessful ()
metode for å finne ut om statuskoden er i området 200-300, som indikerer suksess.onFailure ()
: Påkrevd når et nettverks unntak skjedde kommunikasjon til serveren eller når et uventet unntak oppstod, håndterer forespørselen eller behandler svaret.For å utføre en synkron forespørsel, kan du bruke henrette()
metode i a Anrop
forekomst. Men vær oppmerksom på at synkroniserte metoder på hoved / UI-tråden vil blokkere alle brukerhandlinger. Så ikke utfør synkroniserte metoder på Android hoved- / brukergrensesnitt! Kjør dem i stedet på en bakgrunnstråd.
RxJava ble integrert i Retrofit 1 som standard, men i Retrofit 2 må du inkludere noen ekstra avhengigheter. Retrofit skip med en standardadapter for utførelse Anrop
forekomster. Så du kan endre Retrofits utførelsesmekanisme for å inkludere RxJava ved å inkludere RxJava CallAdapter
. Dette er trinnene:
Legg til avhengighetene.
kompilere 'io.reactivex: rxjava: 1.1.6' compile 'io.reactivex: rxandroid: 1.2.1' compile 'com.squareup.retrofit2: adapter-rxjava: 2.1.0'
Legg til den nye CallAdapter RxJavaCallAdapterFactory.create ()
når du bygger en Retrofit-forekomst (linje 5).
offentlig statisk Retrofit getClient (String baseUrl) if (retrofit == null) retrofit = ny Retrofit.Builder () .baseUrl (baseUrl) .addCallAdapterFactory (RxJavaCallAdapterFactory.create ()) .addConverterFactory (GsonConverterFactory.create ()) .build (); returnere ettermontering
Oppdater APIService
savePost (String title, String body, String userId)
metode for å bli en observerbar.
@POST ("/ posts") @FormUrlEncoded ObservablesavePost (@Field ("title") Stringtittel, @Field ("body") String body, @Field ("userId") long userId);
Når du gjør forespørsler, svarer vår anonyme abonnent på den observerbare strømmen som avgir hendelser, i vårt tilfelle Post
. De onNext
Metoden kalles da når abonnenten mottar noe arrangement, som deretter sendes til vår showResponse (strengrespons)
metode.
Offentlig tomt sendPost (Stringtittel, Stringlegeme) // RxJava mAPIService.savePost (tittel, kropp, 1) .subscribeOn (Schedulers.io ()). observeOn (AndroidSchedulers.mainThread ()) .subscribe (new Subscriber() @Overtrid offentlig tomgang på Fullført () @Overtrid offentlig tomgang onError (Throwable e) @Overtrid offentlig tomgang påNeste (Post post) showResponse (post.toString ()); );
Sjekk ut Komme i gang med ReactiveX på Android av Ashraff Hathibelagal for å lære mer om RxJava og RxAndroid.
På dette tidspunktet kan du kjøre appen og klikke på send-knappen når du har skrevet inn en tittel og en kropp. Svaret fra API-en vil vises under innleveringsknappen.
Nå som vi vet hvordan du skal utføre en POST
forespørsel, la oss se hvordan vi kan utføre en SETTE
forespør hvilke som oppdaterer enheter. Legg til følgende nye metode for APIService
klasse.
@PUT ("/ innlegg / id") @FormUrlEncoded CallupdatePost (@Path ("id") lang id, @Field ("title") Stringtittel, @Field ("body") String body, @Field ("userId") long userId);
For å oppdatere et innlegg fra API-en, har vi sluttpunktet / Innlegg / id
med Id
være plassholder for iden til innlegget vi vil oppdatere. De @Sti
annotering er den navngitte erstatningen i et URL-banesegment Id
. Vær oppmerksom på at verdier konverteres til streng ved hjelp av String.valueOf (objekt)
og URL-kodet. Hvis verdien allerede er kodet, kan du deaktivere URL-koding slik: @Path (verdi = "navn", kodet = sant)
.
La oss også se hvordan du utfører en SLETT
be om. Ved hjelp av JSONPlaceholder API, for å slette en postressurs, er det nødvendige sluttpunktet / Innlegg / id
med HTTP-metoden SLETT
. Tilbake til vår APIService
grensesnitt, trenger vi bare å inkludere metoden deletePost ()
som vil utføre det. Vi sender inn postens id til metoden, og den blir erstattet i URL-banen Id
.
@DELETE ("/ innlegg / id") RingdeletePost (@Path ("id") lang id);
La oss si at du vil gi brukerne muligheten til å avbryte eller avbryte en forespørsel. Dette er veldig enkelt å gjøre i Retrofit. The Retrofit Anrop
klassen har en metode kalt Avbryt()
Det vil bare gjøre det (linje 32 nedenfor). Denne metoden vil utløse onFailure ()
metode i tilbakeringingen.
Denne metoden kan f.eks. Ringes hvis det ikke er noen Internett-tilkobling eller når det oppstod et uventet unntak som skaper forespørselen eller håndterer svaret. For å vite om forespørselen ble kansellert, bruk metoden isCanceled ()
i Anrop
klasse (linje 20).
privat samtalemCall; ... offentlig sendPost (Stringtittel, Stringlegeme) mCall = mAPIService.savePost (tittel, kropp, 1); mCall.enqueue (ny tilbakeringing () @Overgå offentlig ugyldig påmelding (Ring ring, svar svar) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "post sendt til API." + Response.body (). ToString ()); @Override public void onFailure (Ring call, Throwable t) if (call.isCanceled ()) Log.e (TAG, "forespørsel ble avbrutt"); else Log.e (TAG, "Kan ikke sende innlegg til API."); showErrorMessage (); ); offentlig ugyldig avbrytRequest () mCall.cancel ();
I denne opplæringen lærte du om Retrofit: hvorfor du bør bruke den og hvordan å integrere den i prosjektet ditt for å utføre POST
, SETTE
, SLETT
og avbryt forespørsler. Du lærte også å integrere RxJava med den. I mitt neste innlegg ved å bruke Retrofit, viser jeg deg hvordan du laster opp filer.
Hvis du vil vite mer om Retrofit, kan du se den offisielle dokumentasjonen. Og sjekk ut noen av våre andre opplæringsprogrammer og kurs om Android-utvikling her hos Envato Tuts+!