Sänder data med Retrofit 2 HTTP-klient för Android

Vad du ska skapa

Vad är Retrofit?

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 SIGPOSTASÄTTALAPPA, 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:

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

För protokollbuffertar stöder Retrofit:

  • protobuf: com.squareup.retrofit2: konverter-Protobuf
  • Tråd: com.squareup.retrofit2: konverter-wire

Och för XML Retrofit stöder:

  • Enkel ram: com.squareup.retrofit2: konverter-simpleframework

Så varför använda Retrofit?

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. 

1. Skapa ett Android Studio-projekt

Avfyra Android Studio och skapa ett nytt projekt med en tom aktivitet som heter Huvudaktivitet.

2. Deklarera beroenden

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. 

3. Lägga till Internet Tillstånd

För att utföra nätverksoperationer måste vi inkludera INTERNET tillstånd i ansöknings manifest: AndroidManifest.xml.

           

4. Generera modeller automatiskt

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. 

Importera datamodeller till Android Studio

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 Call savePost (@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.

Använda @Kropp Anteckning

Vi 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 Call sparaPost (@Body Post post);

7. Skapa API-hjälpprogram

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 /

8. Skapa layout

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. 

     

9. Utför POST-förfrågan

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 ring tillbaka).

Förståelse 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.

Synkrona förfrågningar

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.

Använda RxJava 

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:

Steg 1

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'

Steg 2

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 

Steg 3

Uppdatera APIService savePost (String title, String body, String userId) metod för att bli en observerbar. 

@POST ("/ inlägg") @FormUrlEncoded Observable savePost (@Field ("title") Stringtitel, @Field ("body") String body, @Field ("userId") long userId);

Steg 4

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. 

10. Testa appen

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. 

11. Utför en PUT-förfrågan

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 Call updatePost (@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)

12. Utför en DELETE-förfrågan

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") Ring deletePost (@Path ("id") lång id);

13. Avbryta en förfrågan

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 ()Ring upp klass (rad 20). 

privat samtal mCall; ... 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 (); 

Slutsats

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 POSTASÄTTARADERA 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+!

  • Animera din Android App

    Animationer har blivit en viktig del av Android-användarupplevelsen. Subtil, väl utformad animering används över hela Android OS och kan göra din ...
    Ashraff Hathibelagal
    Mobil utveckling
  • Praktisk samtidighet på Android med HaMeR

    I den här handledningen utforskar vi HaMeR (Handler, Message and Runnable) -ramen, en av de mest kraftfulla samtidiga modellerna som finns tillgängliga på Android. Med en…
    Tin Megali
    Android SDK
  • Kodning av funktionella Android-appar i Kotlin: Komma igång

    Hörde positiva saker om Kotlins språk för Android-appar och vill prova det själv? Ta reda på hur du installerar och börjar kodning i den här nya ...
    Jessica Thornsby
    Android Studio
  • Migrera en Android App till Material Design

    För flera år sedan, när Android fortfarande var ett spirande mobilt operativsystem, var det ganska ökänt för sitt fula användargränssnitt. Eftersom det inte fanns någon design ...
    Ashraff Hathibelagal
    Android