Retrofit är en typsäker HTTP-klient för Android och Java. Retrofit gör det enkelt att ansluta till en REST webbtjänst genom att översätta API: n till Java-gränssnitt. I den här handledningen visar jag dig hur du använder ett av de mest populära och ofta rekommenderade HTTP-biblioteken som är tillgängliga för Android.
Det här kraftfulla biblioteket gör det enkelt att konsumera JSON- eller XML-data, som sedan analyseras till vanliga gamla Java-objekt (POJOs). SKAFFA SIG
, POSTA
, SÄTTA
, LAPPA
, och RADERA
Förfrågningar kan alla utföras.
Liksom de flesta open source-programvaror, byggdes Retrofit på toppen av några andra kraftfulla bibliotek och verktyg. Bakom kulisserna använder Retrofit OkHttp (från samma utvecklare) för att hantera nätverksförfrågningar. Dessutom har Retrofit inte en inbyggd JSON-omvandlare för att analysera från JSON till Java-objekt. I stället skickar det stöd för följande JSON-omvandlarbibliotek för att hantera det:
com.squareup.retrofit: konverter-gson
com.squareup.retrofit: konverter-Jackson
com.squareup.retrofit: konverter-moshi
För protokollbuffertar stöder Retrofit:
com.squareup.retrofit2: konverter-Protobuf
com.squareup.retrofit2: konverter-wire
Och för XML Retrofit stöder:
com.squareup.retrofit2: konverter-simpleframework
Att utveckla ditt eget typsäkra HTTP-bibliotek till gränssnittet med ett REST-API kan vara en verklig smärta: du måste hantera många aspekter, till exempel anslutningar, cachning, omprövning av misslyckade förfrågningar, threading, responsanalys, felhantering och mer. Retrofit är å andra sidan ett välplanerat, dokumenterat och testat bibliotek som kommer att spara dig mycket dyrbar tid och huvudvärk.
I denna handledning kommer jag att förklara hur man använder Retrofit 2 för att hantera nätverksförfrågningar genom att bygga en enkel app som ska utföra POSTA
förfrågningar, SÄTTA
förfrågningar (för att uppdatera enheter) och RADERA
förfrågningar. Jag ska också visa hur du integrerar med RxJava och hur man avbryter förfrågningar. Vi använder API som tillhandahålls av JSONPlaceholder-det här är ett falskt online REST API för testning och prototypning.
Kolla in mitt tidigare inlägg, Kom igång med Retrofit 2 HTTP-klient, för att lära dig hur du kör SKAFFA SIG
önskemål och hur man integrerar Retrofit med RxJava.
Avfyra Android Studio och skapa ett nytt projekt med en tom aktivitet som heter Huvudaktivitet
.
Efter att ha skapat ett nytt projekt, förklara följande beroenden i din build.gradle
. Berörelserna inkluderar Retrofit-biblioteket och även Googles Gson-bibliotek för att konvertera JSON till POJO (Plain Old Java Objects) samt Retrofits Gson-integration.
// Retrofit compile 'com.squareup.retrofit2: retrofit: 2.1.0' // JSON Parsing compile 'com.google.code.gson: gson: 2.6.1 "kompilera" com.squareup.retrofit2: converter-gson: 2.1 0,0'
Se till att du synkroniserar ditt projekt efter att du har lagt till beroenden.
För att utföra nätverksoperationer måste vi inkludera INTERNET
tillstånd i ansöknings manifest: AndroidManifest.xml.
Vi kommer att skapa modeller automatiskt från JSON-responsdata genom att använda ett mycket användbart verktyg: jsonschema2pojo. Vi skulle vilja göra en POSTA
begär (skapa en ny resurs) på API: n. Men innan vi utför den här förfrågan behöver vi veta det JSON-svar vi borde förvänta oss när det körs så att Retrofit kan analysera JSON-svaret och deserialisera det till Java-objekt. Enligt API: n, om vi skickar följande data i en POSTA
begäran:
data: title: 'foo', body: 'bar', userId: 1
Vi borde få följande svar:
"title": "foo", "body": "bar", "userId": 1, "id": 101
Karta JSON Data till Java
Kopiera provresponsdata från föregående avsnitt. Besök nu jsonschema2pojo och klistra in JSON-svaret i inmatningsrutan. Välj källa typ av JSON, anteckningsstil av Gson, avmarkera Tillåt ytterligare egenskaper, och ändra klassnamnet från Exempel till Posta.
Klicka sedan på Förhandsvisning knappen för att generera Java-objekten.
Du kanske undrar vad @SerializedName
och @Översikt
Anteckningar gör i denna genererade kod! Oroa dig inte, jag förklarar allt!
De @SerializedName
Anmärkning behövs för att Gson ska kunna kartlägga JSON-tangenterna till Java-objektfält.
@SerializedName ("userId") @Expose Private Integer userId;
I det här fallet är JSON-tangenten användar ID
är mappad till klassfältet användar ID
. Men observera att eftersom de är desamma är det inte nödvändigt att inkludera @SerializedName
anteckning på fältet eftersom Gson kommer att kartlägga det automatiskt för oss.
De @Översikt
Anmärkning indikerar att klassmedlemmen ska utsättas för JSON-serialisering eller deserialisering.
Låt oss nu gå tillbaka till Android Studio. Skapa ett nytt delpaket inuti huvud
paket och namnge det data
. Inne i det nyskapade paketet, skapa ett annat paket och namnge det modell
. Inne i det här paketet skapar du en ny Java-klass och heter den Posta
. Kopiera nu Posta
klass som genererades av jsonschema2pojo och klistra in den i Posta
klass du skapade.
paketet com.chikeandroid.retrofittutorial2.data.model; importera com.google.gson.annotations.Expose; importera com.google.gson.annotations.SerializedName; Public Class Post @SerializedName ("title") @Expose Private String title; @SerializedName ("body") @Expose Private String Body; @SerializedName ("userId") @Expose Private Integer userId; @SerializedName ("id") @Expose privat integer-id; public String getTitle () retur titel; public void setTitle (String title) this.title = title; Offentlig String getBody () return body; public void setBody (String body) this.body = body; Public Integer getUserId () return userId; public void setUserId (Integer userId) this.userId = userId; allmän integer getId () return id; public void setId (Integer ID) this.id = id; @Override public String toString () return "Post " + title = '"+ title +' \" + ", + body +" \ "+", userId = "+ userId +", / inlägg ") @FormUrlEncoded CallsavePost (@Field ("title") Stringtitel, @Field ("body") String body, @Field ("userId") long userId);
Titta på APIService
klass, vi har en metod som heter spara inlägget()
. På toppen av metoden är @POSTA
anteckning, vilket indikerar att vi vill utföra en POSTA
Begär när denna metod kallas. Argumentvärdet för @POSTA
Anmärkning är slutpunkten - vilket är / inlägg
. Så hela webbadressen kommer att vara http://jsonplaceholder.typicode.com/posts.
Okej, så hur är det med @FormUrlEncoded
? Detta kommer att indikera att förfrågan kommer att ha sin MIME-typ (ett rubrikfält som identifierar formatet för en HTTP-begäran eller ett svar) som är inställt på application / x-www-form-urlencoded
och även att dess fältnamn och värden kommer att kodas UTF-8 innan de är URI-kodade. De @Field ( "nyckel")
Anmärkning med parameternamn ska matcha det namn som API förväntar sig. Retrofit omvandlar implicit värdena till strängar med String.valueOf (Objekt)
, och strängarna bildar sedan URL-kodade. null
värden ignoreras.
Till exempel ringer APIService.savePost ("Mitt besök till Lagos", "Jag besökte ...", 2)
ger en begäran om title = Min + Besök + Till + Lagos & body = I + besökta ... & userId = 2
.
@Kropp
AnteckningVi kan också använda @Kropp
annotering på en servicemetodsparameter istället för att ange en formformad förfrågan med ett antal enskilda fält. Objektet kommer serialiseras med hjälp av Retrofit
exempel Omvandlare
specificeras under skapandet. Detta används endast när du utför antingen a POSTA
eller SÄTTA
drift.
@POST ("/ inlägg") @FormUrlEncoded CallsparaPost (@Body Post post);
Vi ska skapa en verktygsklass. Så skapa en klass i data.remote
och namnge det ApiUtils
. Denna klass kommer att ha basadressen som en statisk variabel och kommer också att ge APIService
gränssnitt med med a getAPIService ()
statisk metod för resten av vår ansökan.
paketet com.chikeandroid.retrofittutorial2.data.remote; offentlig klass ApiUtils privat ApiUtils () offentliga statiska slutliga sträng BASE_URL = "http://jsonplaceholder.typicode.com/"; offentliga statiska APIService getAPIService () returnera RetrofitClient.getClient (BASE_URL) .create (APIService.class);
Se till att du avslutar basadressen med en /
.
Filen activity_main.xml är layouten för vår Huvudaktivitet
. Denna layout kommer att ha ett textredigeringsfält för titeln på inlägget och ett annat för postens kropp. Det innehåller också en knapp för att skicka inlägget till API: n.
I onCreate ()
metod i Huvudaktivitet
, vi initierar en instans av APIService
gränssnitt (linje 14). Vi initierar också Redigera text
fält och en inmatningsknapp som kommer att ringa sendPost ()
metod när du klickat (linje 22).
privat textvy mResponseTv; privat APIService 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); Knapp 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 (Visa vy) String title = titleEt.getText (). toString (). trim (); String body = bodyEt.getText () .String () .trim (); if (! TextUtils.isEmpty (title) &&! TextUtils.isEmpty (kropp)) sendPost (titel, kropp););
I sendpost (sträng, sträng)
metod i Huvudaktivitet
klass, vi passerade i titeln och kroppen av posten till denna metod. Vad den här metoden gör är att ringa till API-servicegränssnittsmetoden sparaPost (String, String)
vars jobb är att utföra en POSTA
Be om att skicka titeln och kroppen till API: n. De showResponse (string response)
Metoden visar svaret på skärmen.
public void sendPost (String title, String body) mAPIService.savePost (titel, kropp, 1) .enqueue (ny återuppringning() @Override public void onResponse (Call ring, svar svar) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "postat till API." + Response.body (). ToString ()); @Override public void onFailure (Ring call, Throwable t) Log.e (TAG, "Kan inte skicka in post till API."); ); public void showResponse (String response) om (mResponseTv.getVisibility () == View.GONE) mResponseTv.setVisibility (View.VISIBLE); mResponseTv.setText (svar);
Vår APIService
exempel mAPIService
metod sparaPost (String, String)
kommer att returnera a Ring upp
exempel som har en metod kallad enqueue (återuppringning
.
enqueue ()
enqueue ()
asynkront skickar begäran och meddelar din app med en återuppringning när ett svar kommer tillbaka. Eftersom denna förfrågan är asynkron hanterar Retrofit utförandet på en bakgrundsgänga så att huvud-UI-tråden inte blockeras eller störs med.
Att använda enqueue ()
metod måste du genomföra två återuppringningsmetoder: onResponse ()
och onFailure ()
. Endast en av dessa metoder kommer att kallas som svar på en given förfrågan.
onResponse ()
: åberopas för ett mottaget HTTP-svar. Denna metod kallas för ett svar som kan hanteras korrekt även om servern returnerar ett felmeddelande. Så om du får en statuskod på 404 eller 500, kommer den här metoden fortfarande att ringas. För att få statuskoden för att du ska kunna hantera situationer baserade på dem kan du använda metoden response.code ()
. Du kan också använda är framgångsrik()
Metod för att ta reda på om statuskoden ligger inom intervallet 200-300, vilket indikerar framgång.onFailure ()
: påkallad när ett nätverksundantag inträffade kommunicera med servern eller när ett oväntat undantag inträffade hantering av begäran eller behandling av svaret.För att utföra en synkron förfrågan kan du använda Kör()
metod i a Ring upp
exempel. Men var medveten om att synkrona metoder på huvud- / användargränssnittet blockerar användaråtgärder. Så kör inte synkrona metoder på Android: s huvud / UI-tråd! I stället kör dem på en bakgrundsgänga.
RxJava integrerades som standard i Retrofit 1, men i Retrofit 2 måste du inkludera några extra beroenden. Omforma fartyg med en standardadapter för körning Ring upp
instanser. Så du kan ändra Retrofits exekveringsmekanism för att inkludera RxJava genom att inkludera RxJava CallAdapter
. Det här är stegen:
Lägg till beroenden.
kompilera 'io.reactivex: rxjava: 1.1.6' kompilera 'io.reactivex: rxandroid: 1.2.1' compile 'com.squareup.retrofit2: adapter-rxjava: 2.1.0'
Lägg till den nya CallAdapter RxJavaCallAdapterFactory.create ()
när du bygger en Retrofit-instans (rad 5).
public static Retrofit getClient (String baseUrl) if (retrofit == null) retrofit = ny Retrofit.Builder () .baseUrl (baseUrl) .addCallAdapterFactory (RxJavaCallAdapterFactory.create ()) .addConverterFactory (GsonConverterFactory.create ()) .build (); returnera eftermontering
Uppdatera APIService
savePost (String title, String body, String userId)
metod för att bli en observerbar.
@POST ("/ inlägg") @FormUrlEncoded ObservablesavePost (@Field ("title") Stringtitel, @Field ("body") String body, @Field ("userId") long userId);
När du gör förfrågningarna svarar vår anonyma abonnent på den observerbara strömmen som avger händelser, i vårt fall Posta
. De onNext
Metoden kallas då när vår abonnent får något evenemang, som sedan skickas till vårt showResponse (string response)
metod.
public void sendPost (String title, String body) // RxJava mAPIService.savePost (titel, kropp, 1) .subscribeOn (Schedulers.io ()). observeOn (AndroidSchedulers.mainThread ()) .subscribe (new Subscriber() @Override public void onCompleted () @Override public void onError (Throwable e) @Override public void onNext (Post post) showResponse (post.toString ()); );
Kolla in Komma igång med ReactiveX på Android av Ashraff Hathibelagal för att lära dig mer om RxJava och RxAndroid.
Vid denna tidpunkt kan du köra appen och klicka på Skicka-knappen när du har skrivit in en titel och en kropp. Svaret från API: n visas under inmatningsknappen.
Nu när vi vet hur man utför en POSTA
förfrågan, låt oss se hur vi kan utföra en SÄTTA
Begär som uppdaterar enheter. Lägg till följande nya metod för APIService
klass.
@PUT ("/ inlägg / id") @FormUrlEncoded CallupdatePost (@Path ("id") lång id, @Field ("title") Strängtitel, @Field ("body") Strängkropp, @Field ("userId") long userId);
För att uppdatera ett inlägg från API: n, har vi slutpunkten / Inlägg / id
med Id
vara en platshållare för postens id som vi vill uppdatera. De @Väg
Anmärkning är den namngivna ersättaren i ett URL-segment Id
. Var medveten om att värdena konverteras till sträng med String.valueOf (Objekt)
och URL-kodad. Om värdet redan är kodat kan du inaktivera URL-kodning så här: @Path (value = "name", encoded = true)
.
Låt oss också se hur du utför en RADERA
begäran. Med hjälp av JSONPlaceholder API, för att radera en postresurs, är den önskade ändpunkten / Inlägg / id
med HTTP-metoden RADERA
. Tillbaka till vårt APIService
gränssnitt, behöver vi bara inkludera metoden deletePost ()
som kommer att utföra det. Vi skickar in postens id till metoden, och det ersätts i URL-banans segment Id
.
@DELETE ("/ inlägg / id") RingdeletePost (@Path ("id") lång id);
Låt oss säga att du vill ge dina användare möjlighet att avbryta eller avbryta en förfrågan. Det här är väldigt lätt att göra i Retrofit. Retrofit Ring upp
klassen har en metod kallad annullera()
det gör just det (rad 32 nedan). Denna metod kommer att utlösa onFailure ()
metod i återuppringningen.
Den här metoden kan till exempel ringas om det inte finns någon internetanslutning eller när ett oväntat undantag inträffade som skapade begäran eller hanterar svaret. Så för att veta om förfrågan annullerades, använd metoden isCanceled ()
i Ring upp
klass (rad 20).
privat samtalmCall; ... public sendPost (String title, String body) mCall = mAPIService.savePost (titel, kropp, 1); mCall.enqueue (ny återkallning () @Override public void onResponse (Call ring, svar svar) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "postat till API." + Response.body (). ToString ()); @Override public void onFailure (Ring call, Throwable t) if (call.isCanceled ()) Log.e (TAG, "begäran avbröts"); else Log.e (TAG, "Kan inte skicka inlägg till API."); showErrorMessage (); ); Offentligt ogiltigt avbrytRequest () mCall.cancel ();
I denna handledning lärde du dig om Retrofit: varför ska du använda det och hur man integrerar det i ditt projekt för att utföra POSTA
, SÄTTA
, RADERA
och avbryta förfrågningar. Du lärde dig också att integrera RxJava med den. I mitt nästa inlägg med hjälp av Retrofit visar jag hur du laddar upp filer.
För mer information om Retrofit, se den officiella dokumentationen. Och kolla in några av våra andra handledning och kurser om Android-utveckling här på Envato Tuts+!