Retrofit è un client HTTP sicuro per tipo per Android e Java. Retrofit semplifica la connessione a un servizio Web REST traducendo l'API in interfacce Java. In questo tutorial, ti mostrerò come utilizzare una delle librerie HTTP più popolari e spesso raccomandate disponibili per Android.
Questa potente libreria semplifica il consumo di dati JSON o XML, che vengono poi analizzati in Plain Old Java Objects (POJO). OTTENERE
, INVIARE
, METTERE
, PATCH
, e ELIMINA
le richieste possono essere tutte eseguite.
Come la maggior parte dei software open source, Retrofit è stato costruito su altre potenti librerie e strumenti. Dietro le quinte, Retrofit utilizza OkHttp (dello stesso sviluppatore) per gestire le richieste di rete. Inoltre, Retrofit non ha un convertitore JSON integrato per analizzare da oggetti JSON a Java. Invece, viene fornito il supporto per le seguenti librerie di convertitori JSON per gestire ciò:
com.squareup.retrofit: convertitore-GSON
com.squareup.retrofit: convertitore-jackson
com.squareup.retrofit: convertitore-moshi
Per i buffer del protocollo, supporta Retrofit:
com.squareup.retrofit2: convertitore-protobuf
com.squareup.retrofit2: convertitore fili
E per XML Retrofit, supporta:
com.squareup.retrofit2: convertitore-simpleframework
Sviluppare la propria libreria HTTP sicura per l'interfaccia con un'API REST può essere un vero problema: è necessario gestire molti aspetti, come l'esecuzione di connessioni, memorizzazione nella cache, riprovare richieste non riuscite, threading, analisi delle risposte, gestione degli errori e altro. Retrofit, d'altra parte, è una libreria ben pianificata, documentata e testata che ti farà risparmiare un sacco di tempo prezioso e mal di testa.
In questo tutorial, spiegherò come utilizzare Retrofit 2 per gestire le richieste di rete creando una semplice app che eseguirà INVIARE
richieste, METTERE
richieste (per aggiornare entità), e ELIMINA
richieste. Ti mostrerò anche come integrare con RxJava e come annullare le richieste. Useremo l'API fornita da JSONPlaceholder: questa è un'API REST falsa online per test e prototipazione.
Controlla il mio post precedente, Get Started With Retrofit 2 Client HTTP, per imparare come eseguire OTTENERE
richieste e come integrare Retrofit con RxJava.
Avvia Android Studio e crea un nuovo progetto con un'attività vuota chiamata Attività principale
.
Dopo aver creato un nuovo progetto, dichiara le seguenti dipendenze nel tuo build.gradle
. Le dipendenze includono la libreria Retrofit e anche la libreria Gson di Google per convertire JSON in POJO (Plain Old Java Objects) e l'integrazione di Gof di Retrofit.
// Retrofit compile 'com.squareup.retrofit2: retrofit: 2.1.0' // JSON Parsing compile 'com.google.code.gson: gson: 2.6.1' compile 'com.squareup.retrofit2: convertitore-gson: 2.1 0,0'
Assicurati di sincronizzare il progetto dopo aver aggiunto le dipendenze.
Per eseguire operazioni di rete, è necessario includere il INTERNET
permesso nel manifest dell'applicazione: AndroidManifest.xml.
Creeremo modelli automaticamente dai dati di risposta JSON sfruttando uno strumento molto utile: jsonschema2pojo. Ci piacerebbe fare un INVIARE
richiesta (creare una nuova risorsa) sull'API. Ma prima di eseguire questa richiesta, dobbiamo conoscere la risposta JSON che dovremmo aspettarci quando viene eseguita correttamente, in modo che Retrofit possa analizzare la risposta JSON e deserializzarla in oggetti Java. Secondo l'API, se inviamo i seguenti dati in a INVIARE
richiesta:
data: title: 'foo', body: 'bar', userId: 1
Dovremmo ottenere la seguente risposta:
"title": "foo", "body": "bar", "userId": 1, "id": 101
Mappare i dati JSON su Java
Copia i dati di risposta campione dalla sezione precedente. Ora visita jsonschema2pojo e incolla la risposta JSON nella casella di input. Seleziona il tipo di fonte di JSON, stile di annotazione di GSON, deselezionare Consenti proprietà aggiuntive, e cambia il nome della classe da Esempio a Inviare.
Quindi fare clic su Anteprima pulsante per generare gli oggetti Java.
Potresti chiederti che cosa @SerializedName
e @Esporre
le annotazioni fanno in questo codice generato! Non preoccuparti, ti spiegherò tutto!
Il @SerializedName
l'annotazione è necessaria per Gson per mappare le chiavi JSON ai campi degli oggetti Java.
@SerializedName ("userId") @Expose Intero privato ID utente;
In questo caso, la chiave JSON ID utente
è mappato al campo della classe ID utente
. Ma nota che poiché sono uguali, non è necessario includere il @SerializedName
annotazione sul campo perché Gson la mapperà automaticamente per noi.
Il @Esporre
l'annotazione indica che il membro della classe deve essere esposto per la serializzazione o deserializzazione JSON.
Ora torniamo ad Android Studio. Crea un nuovo sottoprogetto all'interno del principale
pacchetto e chiamarlo dati
. All'interno del pacchetto appena creato, crea un altro pacchetto e chiamalo modello
. All'interno di questo pacchetto, creare una nuova classe Java e denominarla Inviare
. Ora copia il Inviare
classe che è stata generata da jsonschema2pojo e incollarla all'interno di Inviare
classe che hai creato.
pacchetto com.chikeandroid.retrofittutorial2.data.model; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; public class Post @SerializedName ("title") @Expose private String title; @SerializedName ("body") @Expose String body privato; @SerializedName ("userId") @Expose Intero privato ID utente; @SerializedName ("id") @Expose ID intero privato; public String getTitle () return title; public void setTitle (String title) this.title = title; public String getBody () return body; public void setBody (Corpo della stringa) this.body = body; public Integer getUserId () return userId; public void setUserId (Integer userId) this.userId = userId; public Intero getId () return id; public void setId (Integer id) this.id = id; @Override public String toString () return "Post " + "title = '" + title +' \ "+", + body + "\" + ", userId =" + userId + ", / posts") Chiamata @FormUrlEncodedsavePost (@Field ("title") Titolo stringa, @Field ("body") Corpo della stringa, @Field ("userId") long ID utente);
Guardando il APIService
classe, abbiamo un metodo chiamato savePost ()
. In cima al metodo è il @INVIARE
annotazione, che indica che vogliamo eseguire a INVIARE
richiesta quando viene chiamato questo metodo. Il valore dell'argomento per il @INVIARE
l'annotazione è l'endpoint, che è / messaggi
. Quindi l'URL completo sarà http://jsonplaceholder.typicode.com/posts.
Ok, allora, per quanto riguarda il @FormUrlEncoded
? Questo indicherà che la richiesta avrà il suo tipo MIME (un campo di intestazione che identifica il formato del corpo di una richiesta o risposta HTTP) impostato su application / x-www-form-urlencoded
e anche che i suoi nomi e valori di campo saranno codificati in UTF-8 prima di essere codificati con URI. Il @Field ( "chiave")
l'annotazione con il nome del parametro deve corrispondere al nome che l'API si aspetta. Retrofit converte implicitamente i valori in stringhe usando String.valueOf (Object)
, e le stringhe vengono quindi codificate come URL. nullo
i valori sono ignorati.
Ad esempio, chiamando APIService.savePost ("La mia visita a Lagos", "Ho visitato ...", 2)
produce un corpo di richiesta di title = My + Visit + To + Lagos & body = I + visited ... & userId = 2
.
@Corpo
AnnotazionePossiamo anche usare il @Corpo
annotazione su un parametro del metodo di servizio invece di specificare un corpo di richiesta in stile modulo con un numero di singoli campi. L'oggetto sarà serializzato usando il Retrofit
esempio Converter
specificato durante la creazione. Questo è usato solo quando si esegue uno a INVIARE
o METTERE
operazione.
@POST ("/ posts") Chiamata @FormUrlEncodedsavePost (@Body Post post);
Creeremo una classe di utilità. Quindi crea una classe in data.remote
e nominalo ApiUtils
. Questa classe avrà l'URL di base come variabile statica e fornirà anche il APIService
interfaccia con a getAPIService ()
metodo statico per il resto della nostra applicazione.
pacchetto com.chikeandroid.retrofittutorial2.data.remote; public class ApiUtils private ApiUtils () public static final String BASE_URL = "http://jsonplaceholder.typicode.com/"; public static APIService getAPIService () return RetrofitClient.getClient (BASE_URL) .create (APIService.class);
Assicurati di terminare l'URL di base con un /
.
Il file activity_main.xml è il layout per il nostro Attività principale
. Questo layout avrà un campo di modifica del testo per il titolo del post e un altro per il corpo del post. Include anche un pulsante per inviare il post all'API.
Nel onCreate ()
metodo in Attività principale
, inizializziamo un'istanza di APIService
interfaccia (riga 14). Inizializziamo anche il Modifica il testo
campi e un pulsante di invio che chiamerà il sendPost ()
metodo quando cliccato (riga 22).
TextView privato mResponseTv; APIService privato MAPIService; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); EditText titleTesto = (EditText) findViewById (R.id.et_title); EditText finale 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 (Visualizza vista) String title = titleEt.getText (). toString (). trim (); String body = bodyEt.getText (). toString () .trim (); if (! TextUtils.isEmpty (title) &&! TextUtils.isEmpty (body)) sendPost (titolo, corpo););
Nel sendPost (String, String)
metodo nel Attività principale
classe, abbiamo passato il titolo e il corpo del post a questo metodo. Ciò che questo metodo farà è chiamare il nostro metodo di interfaccia del servizio API savePost (String, String)
il cui compito è eseguire a INVIARE
richiedere l'invio del titolo e del corpo all'API. Il showResponse (String response)
il metodo mostrerà la risposta sullo schermo.
public void sendPost (String title, String body) mAPIService.savePost (title, body, 1) .enqueue (new Callback() @ Override public void onResponse (Call chiamata, risposta risposta) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "post submit to API." + Response.body (). ToString ()); @Override public void onFailure (Call call, Throwable t) Log.e (TAG, "Impossibile inviare post all'API."); ); public void showResponse (String response) if (mResponseTv.getVisibility () == View.GONE) mResponseTv.setVisibility (View.VISIBLE); mResponseTv.setText (risposta);
Nostro APIService
esempio mAPIService
metodo savePost (String, String)
restituirà a Chiamata
istanza che ha un metodo chiamato enqueue (Richiamata
.
enqueue ()
enqueue ()
invia in modo asincrono la richiesta e avvisa la tua app con un callback quando ritorna una risposta. Poiché questa richiesta è asincrona, Retrofit gestisce l'esecuzione su un thread in background in modo che il thread dell'interfaccia utente principale non sia bloccato o interferito con.
Per usare il enqueue ()
metodo, è necessario implementare due metodi di callback: onResponse ()
e onFailure ()
. Solo uno di questi metodi verrà chiamato in risposta a una determinata richiesta.
onResponse ()
: invocato per una risposta HTTP ricevuta. Questo metodo viene chiamato per una risposta che può essere gestita correttamente anche se il server restituisce un messaggio di errore. Quindi se ottieni un codice di stato 404 o 500, questo metodo verrà comunque chiamato. Per ottenere il codice di stato al fine di gestire le situazioni basate su di essi, è possibile utilizzare il metodo Codice di risposta()
. Puoi anche usare il isSuccessful ()
metodo per scoprire se il codice di stato è nell'intervallo 200-300, indicando il successo.onFailure ()
: richiamato quando si è verificata un'eccezione di rete che comunica al server o quando si è verificata un'eccezione imprevista durante la gestione della richiesta o l'elaborazione della risposta.Per eseguire una richiesta sincrona, è possibile utilizzare il eseguire()
metodo in a Chiamata
esempio. Ma tieni presente che i metodi sincroni sul thread principale / dell'interfaccia utente bloccheranno qualsiasi azione dell'utente. Quindi non eseguire metodi sincroni sul thread principale / dell'interfaccia utente di Android! Piuttosto eseguili su un thread in background.
RxJava è stato integrato in Retrofit 1 per impostazione predefinita, ma in Retrofit 2 è necessario includere alcune dipendenze aggiuntive. Il retrofit viene fornito con un adattatore predefinito per l'esecuzione Chiamata
le istanze. Quindi è possibile modificare il meccanismo di esecuzione di Retrofit per includere RxJava includendo RxJava CallAdapter
. Questi sono i passaggi:
Aggiungi le dipendenze.
compile 'io.reactivex: rxjava: 1.1.6' compila 'io.reactivex: rxandroid: 1.2.1' compile 'com.squareup.retrofit2: adapter-rxjava: 2.1.0'
Aggiungi il nuovo CallAdapter RxJavaCallAdapterFactory.create ()
quando si crea un'istanza di Retrofit (riga 5).
public static Retrofit getClient (String baseUrl) if (retrofit == null) retrofit = new Retrofit.Builder () .baseUrl (baseUrl) .addCallAdapterFactory (RxJavaCallAdapterFactory.create ()) .addConverterFactory (GsonConverterFactory.create ()) .build (); retrofit di ritorno;
Aggiorna il APIService
savePost (titolo stringa, corpo stringa, stringa userId)
metodo per diventare osservabile.
@POST ("/ posts") @FormUrlEncoded ObservablesavePost (@Field ("title") Titolo stringa, @Field ("body") Corpo della stringa, @Field ("userId") long ID utente);
Quando facciamo le richieste, il nostro abbonato anonimo risponde allo stream osservabile che emette eventi, nel nostro caso Inviare
. Il onNext
il metodo viene quindi chiamato quando il nostro abbonato riceve un evento, che viene poi passato al nostro showResponse (String response)
metodo.
public void sendPost (String title, String body) // RxJava mAPIService.savePost (title, body, 1) .subscribeOn (Schedulers.io ()). observOn (AndroidSchedulers.mainThread ()) .subscribe (new Subscriber() @Override public void onCompleted () @Override public void onError (Throwable e) @Override public void onNext (Post post) showResponse (post.toString ()); );
Scopri come iniziare con ReactiveX su Android di Ashraff Hathibelagal per saperne di più su RxJava e RxAndroid.
A questo punto, puoi eseguire l'app e fare clic sul pulsante di invio quando hai inserito un titolo e un corpo. La risposta dall'API mostrerà sotto il pulsante di invio.
Ora sappiamo come eseguire a INVIARE
richiesta, vediamo come possiamo eseguire a METTERE
richiesta che aggiorna le entità. Aggiungi il seguente nuovo metodo al APIService
classe.
@PUT ("/ posts / id") Chiamata @FormUrlEncodedupdatePost (@Path ("id") long id, @Field ("title") Titolo stringa, @Field ("body") Corpo della stringa, @Field ("userId") long ID utente);
Per aggiornare un post dall'API, abbiamo l'endpoint / Messaggi / id
con Id
essere un segnaposto per l'id del post che vogliamo aggiornare. Il @Sentiero
l'annotazione è la sostituzione nominata in un segmento del percorso URL Id
. Tieni presente che i valori vengono convertiti in string usando String.valueOf (Object)
e URL codificati. Se il valore è già codificato, puoi disabilitare la codifica dell'URL in questo modo: @Path (value = "name", encoded = true)
.
Vediamo anche come eseguire a ELIMINA
richiesta. Utilizzando l'API JSONPlaceholder, per eliminare una risorsa post, l'endpoint richiesto è / Messaggi / id
con il metodo HTTP ELIMINA
. Di nuovo al nostro APIService
interfaccia, abbiamo solo bisogno di includere il metodo deletePost ()
che lo eseguirà. Passiamo l'id del post al metodo e viene sostituito nel segmento del percorso URL Id
.
@DELETE ("/ posts / id") ChiamadeletePost (@Path ("id") long id);
Diciamo che vuoi dare ai tuoi utenti la possibilità di annullare o interrompere una richiesta. Questo è molto facile da fare in Retrofit. Il retrofit Chiamata
la classe ha un metodo chiamato Annulla()
quello farà appena quello (riga 32 sotto). Questo metodo attiverà il onFailure ()
metodo nel callback.
Questo metodo può essere chiamato, ad esempio, se non vi è alcuna connessione Internet o quando si è verificata un'eccezione imprevista durante la creazione della richiesta o la gestione della risposta. Quindi per sapere se la richiesta è stata cancellata, usa il metodo isCanceled ()
nel Chiamata
classe (riga 20).
Chiamata privatamCall; ... public sendPost (String title, String body) mCall = mAPIService.savePost (title, body, 1); mCall.enqueue (nuovo Richiamata () @ Override public void onResponse (Call chiamata, risposta risposta) if (response.isSuccessful ()) showResponse (response.body (). toString ()); Log.i (TAG, "post submit to API." + Response.body (). ToString ()); @Override public void onFailure (Call call, Throwable t) if (call.isCanceled ()) Log.e (TAG, "request was aborted"); else Log.e (TAG, "Impossibile inviare post all'API."); showErrorMessage (); ); public void cancelRequest () mCall.cancel ();
In questo tutorial, hai imparato a conoscere Retrofit: perché dovresti usarlo e come integrarlo nel tuo progetto INVIARE
, METTERE
, ELIMINA
e cancella le richieste. Hai anche imparato come integrare RxJava con esso. Nel mio prossimo post sull'uso di Retrofit, ti mostrerò come caricare i file.
Per ulteriori informazioni su Retrofit, fare riferimento alla documentazione ufficiale. E dai un'occhiata ai nostri altri tutorial e corsi sullo sviluppo di Android qui su Envato Tuts+!