Sende data med Retrofit 2 HTTP-klient for Android

Hva du skal skape

Hva er Retrofit?

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). POSTSETTELAPP, 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:

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

For protokollbuffere støtter Retrofit:

  • Protobuf: com.squareup.retrofit2: converter-Protobuf
  • Metalltråd: com.squareup.retrofit2: konverter-ledning

Og for XML Retrofit, støtter:

  • Enkel ramme: com.squareup.retrofit2: converter-simpleframework

Så hvorfor bruk Retrofit?

Å 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  forespørsler og hvordan å integrere Retrofit med RxJava. 

1. Opprett et Android Studio-prosjekt

Brann opp Android Studio og opprett et nytt prosjekt med en tom aktivitet som heter Hoved aktivitet.

2. Deklarere avhengigheter

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. 

3. Legge til internettillatelse

For å utføre nettverksoperasjoner må vi inkludere INTERNETT Tillatelse i søknadsmanifestet: AndroidManifest.xml.

           

4. Generere modeller automatisk

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. 

Importer datamodeller til Android Studio

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

Bruker @Kropp merknad

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

7. Opprette API-verktøyene

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 /

8. Lag oppsettet

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. 

     

9. Utfør POST-forespørselen

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 Ring tilbake).

forståelse 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.

Synkron forespørsler

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.

Bruke RxJava 

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:

Trinn 1

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'

Steg 2

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 

Trinn 3

Oppdater APIService savePost (String title, String body, String userId) metode for å bli en observerbar. 

@POST ("/ posts") @FormUrlEncoded Observable savePost (@Field ("title") Stringtittel, @Field ("body") String body, @Field ("userId") long userId);

Trinn 4

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. 

10. Testing av appen

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. 

11. Utfør en PUT-forespørsel

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

12. Utfør en DELETE forespørsel

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

13. Avbryte en forespørsel

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 ()Anrop klasse (linje 20). 

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

Konklusjon

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 POSTSETTESLETT 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+!

  • Animer Android-appen din

    Animasjoner har blitt en viktig del av Android-brukeropplevelsen. Subtil, godt utformet animasjon brukes i hele Android OS og kan gjøre din ...
    Ashraff Hathibelagal
    Mobil utvikling
  • Praktisk samtidighet på Android med HaMeR

    I denne opplæringen vil vi utforske HaMeR (Handler, Message and Runnable) rammeverket, en av de kraftigste samtidige modellene som er tilgjengelige på Android. Med en…
    Tin Megali
    Android SDK
  • Koding Funksjonelle Android-apper i Kotlin: Komme i gang

    Hørt positive ting om Kotlin-språket for Android-apper og vil prøve det selv? Finn ut hvordan du konfigurerer og starter koding i denne nye ...
    Jessica Thornsby
    Android Studio
  • Overfør en Android-app til Material Design

    For mange år siden, da Android fortsatt var et spirende mobiloperativsystem, var det ganske beryktet for sitt gale brukergrensesnitt. Fordi det ikke var noe design ...
    Ashraff Hathibelagal
    Android