Invio di dati con il client HTTP Retrofit 2 per Android

Cosa starai creando

Che cosa è il retrofit?

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

  • GSON: com.squareup.retrofit: convertitore-GSON
  • Jackson: com.squareup.retrofit: convertitore-jackson
  • Moshi: com.squareup.retrofit: convertitore-moshi

Per i buffer del protocollo, supporta Retrofit:

  • Protobuf: com.squareup.retrofit2: convertitore-protobuf
  • Filo: com.squareup.retrofit2: convertitore fili

E per XML Retrofit, supporta:

  • Quadro semplice: com.squareup.retrofit2: convertitore-simpleframework

Quindi, perché utilizzare Retrofit?

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. 

1. Creare un progetto per Android Studio

Avvia Android Studio e crea un nuovo progetto con un'attività vuota chiamata Attività principale.

2. Dichiarare le dipendenze

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. 

3. Aggiunta dell'autorizzazione Internet

Per eseguire operazioni di rete, è necessario includere il INTERNET permesso nel manifest dell'applicazione: AndroidManifest.xml.

           

4. Generazione automatica di modelli

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. 

Importa modelli di dati su Android Studio

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

Usando il @Corpo Annotazione

Possiamo 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 @FormUrlEncoded savePost (@Body Post post);

7. Creazione delle utilità API

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 /

8. Creazione del layout

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. 

     

9. Esecuzione della richiesta POST

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 richiama).

Comprensione 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 ()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.

Richieste sincrone

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.

Utilizzando RxJava 

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:

Passo 1

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'

Passo 2

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; 

Passaggio 3

Aggiorna il APIService savePost (titolo stringa, corpo stringa, stringa userId) metodo per diventare osservabile. 

@POST ("/ posts") @FormUrlEncoded Observable savePost (@Field ("title") Titolo stringa, @Field ("body") Corpo della stringa, @Field ("userId") long ID utente);

Passaggio 4

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. 

10. Testare l'app

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. 

11. Esecuzione di una richiesta PUT

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

12. Esecuzione di una richiesta DELETE

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

13. Annullamento di una richiesta

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

Conclusione

In questo tutorial, hai imparato a conoscere Retrofit: perché dovresti usarlo e come integrarlo nel tuo progetto INVIAREMETTEREELIMINA 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+!

  • Anima la tua app per Android

    Le animazioni sono diventate una parte importante dell'esperienza utente di Android. Un'animazione sottile e ben realizzata è utilizzata in tutto il sistema operativo Android e può rendere ...
    Ashraff Hathibelagal
    Sviluppo mobile
  • Concorrenza pratica su Android con HaMeR

    In questo tutorial esploreremo il framework HaMeR (Handler, Message and Runnable), uno dei più potenti modelli di concorrenza disponibili su Android. Con un…
    Tin Megali
    SDK Android
  • Codifica delle app Android funzionali in Kotlin: come iniziare

    Hai sentito cose positive sul linguaggio Kotlin per le app Android e vuoi provarlo tu stesso? Scopri come impostare e avviare la codifica in questo nuovo ...
    Jessica Thornsby
    Studio Android
  • Migrare un'app Android a Material Design

    Anni fa, quando Android era ancora un sistema operativo mobile in erba, era piuttosto noto per la sua brutta interfaccia utente. Perché non c'erano progetti ...
    Ashraff Hathibelagal
    androide