Un'introduzione a Volley

Volley è una libreria di rete sviluppata da Google e introdotta durante Google I / O 2013. È stata sviluppata a causa dell'assenza, nell'SDK Android, di una classe di rete in grado di funzionare senza interferire con l'esperienza dell'utente.

Fino all'uscita di Volley, la classe canonica di Java java.net.HttpURLConnection e l'Apache org.apache.http.client erano gli unici strumenti disponibili per i programmatori Android per sviluppare un sistema RESTful tra un client e un back-end remoto.

Mettendo da parte per un momento il fatto che queste due classi non sono esenti da bug, si dovrebbe notare come tutto ciò che andava oltre una semplice transazione HTTP doveva essere scritto ex novoSe si desidera memorizzare nella cache le immagini o dare priorità alle richieste, è necessario svilupparle da zero.

Fortunatamente, ora c'è Volley, creata e adattata per soddisfare queste esigenze.

1. Perché Volley?

Evitare HttpURLConnection e HttpClient

Su livelli API inferiori (principalmente su Gingerbread e Froyo), HttpURLConnectionHttpClient sono lontani dall'essere perfetti. Ci sono alcuni noti e bug che non sono mai stati corretti. inoltre, HttpClient è stato deprecato nell'ultimo aggiornamento dell'API (API 22), il che significa che non verrà più gestito e potrebbe essere rimosso in una versione futura.

Questi sono motivi sufficienti per decidere di passare a un modo più affidabile di gestire le richieste di rete.

Ed evitare AsyncTask Pure

Dall'introduzione di Honeycomb (API 11), è stato obbligatorio eseguire operazioni di rete su un thread separato, diverso dal thread principale. Questo sostanziale cambiamento ha aperto la strada a un uso massiccio del AsyncTask specificazione.

Con AsyncTask, per prima cosa definite alcune azioni preparatorie, come la definizione del contesto, in OnPreExecute. Quindi esegui le tue attività asincrone usando il doInBackground metodo. Infine, gestisci i risultati in OnPostExecute. È piuttosto semplice, molto più semplice dell'implementazione di un servizio e viene fornito con un sacco di esempi e documentazione.

Il problema principale, tuttavia, è la serializzazione delle chiamate. Usando il AsyncTask classe, non puoi decidere quale sia la prima richiesta e quale deve aspettare. Tutto accade FIFO, primo in, primo fuori.

I problemi sorgono, ad esempio, quando devi caricare un elenco di elementi che hanno allegato una miniatura. Quando l'utente scorre verso il basso e si aspetta nuovi risultati, non puoi dire alla tua attività di caricare prima il JSON della pagina successiva e solo le immagini della pagina precedente. Questo può diventare un serio problema di esperienza utente in applicazioni come Facebook o Twitter, dove l'elenco di nuovi elementi è più importante della miniatura associata ad esso.

Volley mira a risolvere questo problema includendo una potente API di cancellazione. Non è più necessario il check-in OnPostExecute se l'attività è stata distrutta durante l'esecuzione della chiamata. Questo aiuta a evitare un indesiderato NullPointerException.

È molto più veloce

Qualche tempo fa, il team di Google+ ha eseguito una serie di test delle prestazioni su ciascuno dei diversi metodi che è possibile utilizzare per effettuare richieste di rete su Android. Volley ha ottenuto un punteggio fino a dieci volte migliore rispetto alle altre alternative se utilizzato nelle applicazioni RESTful.

Cache tutto

Volley memorizza automaticamente le richieste e questo è qualcosa che salva davvero la vita. Ritorniamo per un momento all'esempio che ho dato in precedenza. Hai una lista di elementi - diciamo una matrice JSON - e ogni oggetto ha una descrizione e una miniatura associata. Ora pensa a cosa succede se l'utente ruota lo schermo: l'attività viene distrutta, l'elenco viene scaricato di nuovo e così anche le immagini. Per farla breve, uno spreco significativo di risorse e una scarsa esperienza utente.

Volley si rivela estremamente utile per superare questo problema. esso ricorda le chiamate precedenti lo ha fatto e gestisce l'attività di distruzione e ricostruzione. Mette in cache tutto senza che tu debba preoccuparti di ciò.

Piccole operazioni sui metadati

Volley è perfettoper chiamate di piccole dimensioni, come oggetti JSON, porzioni di elenchi, dettagli di un elemento selezionato e così via. È stato ideato per applicazioni RESTful e in questo caso particolare dà il meglio.

Non è così buono, tuttavia, quando viene utilizzato per operazioni di streaming e download di grandi dimensioni. Contrariamente alla credenza comune, il nome di Volley non viene dal dizionario dello sport. È piuttosto inteso come ripetute raffiche di chiamate, raggruppate insieme. È in qualche modo intuitivo perché questa libreria non sia utile quando, invece di una raffica di frecce, vuoi sparare una palla di cannone.

2. Sotto il cofano

Volley funziona su tre diversi livelli con ogni livello che opera su una propria thread.

Filo principale

Sul thread principale, coerentemente con quello che già fai in AsyncTask specifica, è possibile solo attivare la richiesta e gestire la sua risposta. Niente di più, niente di meno.

La principale conseguenza è che puoi effettivamente ignorare tutto ciò che stava succedendo nel doInBackground metodo. Volley gestisce automaticamente le transazioni HTTP e gli errori di rete che dovevano interessare prima.

Thread di cache e di rete

Quando aggiungi una richiesta alla coda, accadono diverse cose sotto il cofano. Innanzitutto, Volley controlla se la richiesta può essere riparata dalla cache. Se possibile, la risposta memorizzata nella cache viene letta, analizzata e consegnata. Altrimenti viene passato al thread di rete.

Sul thread di rete, un round-robin con una serie di thread è costantemente funzionante. Il primo thread di rete disponibile rimuove la richiesta, effettua la richiesta HTTP, analizza la risposta e la scrive nella cache. Per finire, invia la risposta analizzata al thread principale in cui gli ascoltatori sono in attesa di gestire il risultato.

3. Iniziare

Step 1: Importare Volley

Volley non è così pratico da configurare. Sembra che non ci sia un repository Maven ufficiale disponibile e questo è piuttosto sconcertante. Devi fare affidamento sul codice sorgente ufficiale. Puoi importare Volley in vari modi.

Per prima cosa, scarica il sorgente Volley dal suo repository. Se ti senti sicuro di farlo, questo Gitil comando può fare tutto il lavoro per te:

git clone https://android.googlesource.com/platform/frameworks/volley

Fino a qualche settimana fa, puoi avvolgere tutto usando il formica riga di comando (progetto di aggiornamento android -p . e poi barattolo di formica) e importando il tuo VASO libreria nel tuo progetto Android Studio con un semplice file di compilazione ('libs / volley.jar').

Di recente, però, Google ha aggiornato Volley nello stile di build di Android Studio, rendendo più difficile la creazione di uno standalone VASO. Puoi ancora farlo, ma solo con versioni precedenti della libreria. Ti scoraggio personalmente a utilizzare questa opzione, anche se può sembrare la più veloce.

Dovresti configurare Volley the modo classico, cioè importando la sorgente come a modulo. In Android Studio, con il tuo progetto aperto, seleziona File> Nuovo modulo, e selezionare Importa progetto esistente. Seleziona la directory in cui hai appena scaricato il codice sorgente e conferma. Una cartella denominata Volley verrà visualizzata nella struttura del progetto. Android Studio aggiorna automaticamente il tuo settings.gradle file per includere il modulo Volley, quindi è sufficiente aggiungere alle dipendenze progetto di compilazione (': volley') e hai finito.

C'è una terza via. È possibile aggiungere alla sezione delle dipendenze di build.gradle file questa riga:

compilare 'com.mcxiaoke.volley: library-aar: 1.0.15'

È una copia speculare del repository ufficiale di Google, regolarmente sincronizzata e aggiornata. È probabilmente il modo più semplice e veloce per iniziare. Tuttavia, sii consapevole, è un non ufficiale Repository Maven, nessuna garanzia e non supportato da Google.

A mio parere, è ancora meglio investire qualche minuto in più per importare il codice sorgente ufficiale. In questo modo, puoi facilmente saltare alle definizioni e alle implementazioni originali in modo che, in caso di dubbio, puoi sempre fare affidamento sulla fonte ufficiale di Volley e persino cambiarla se hai bisogno di.

Passaggio 2: utilizzo di Volley

Volley funziona principalmente con solo due classi, RequestQueue e Richiesta. Per prima cosa crea un RequestQueue, che gestisce i thread di lavoro e restituisce i risultati analizzati al thread principale. Poi lo passi uno o più Richiesta oggetti.

Il Richiesta il costruttore prende sempre come parametri il tipo di metodo (GET, POST, ecc.), l'URL della risorsa e i listener di eventi. Quindi, a seconda del tipo di richiesta, potrebbe richiedere alcune più variabili.

Nell'esempio seguente, creo a RequestQueueoggetto invocando uno dei metodi di convenienza di Volley, Volley.newRequestQueue. Questo imposta a RequestQueueoggetto, utilizzando i valori predefiniti definiti da Volley.

String url = "http://httpbin.org/html"; // Richiedi una risposta stringa StringRequest stringRequest = new StringRequest (Request.Method.GET, url, new Response.Listener() @Override public void onResponse (String response) // Gestione dei risultati System.out.println (response.substring (0,100)); , new Response.ErrorListener () @Override public void onErrorResponse (Errore VolleyError) // Gestione errori System.out.println ("Qualcosa è andato storto!"); error.printStackTrace (); ); // Aggiungi la richiesta alla coda Volley.newRequestQueue (this) .add (stringRequest); 

Come puoi vedere, è incredibilmente semplice. La richiesta viene creata e aggiunta alla coda della richiesta. E hai finito.

Si noti che la sintassi del listener è simile a AsyncTask.onPostExecute, diventa semplicemente onResponse. Questa non è una coincidenza. Gli sviluppatori che hanno lavorato su Volley hanno fatto intenzionalmente l'API della libreria in modo simile a AsyncTask metodi. Questo rende la transizione dall'uso AsyncTask a Volley è molto più facile.

Se devi attivare più richieste in più attività, dovresti evitare di utilizzare l'approccio sopra, Volley.newRequestQueue.add. È moltomeglio istanziare una coda di richieste condivise e utilizzarla attraverso il tuo progetto:

. MySingletonClass.getInstance () getRequestQueue () aggiungere (myRequest).;

Vedremo in particolare di sviluppare qualcosa di simile nel prossimo tutorial di questa serie.

4. Metti le mani nell'impasto

Gestione di richieste standard

Volley è utile per implementare tre tipi di richieste molto comuni:

  • StringRequest
  • ImageRequest
  • JsonRequest

Ognuna di queste classi estende il Risultato classe che abbiamo usato in precedenza. Abbiamo già guardato il StringRequest nell'esempio precedente. Vediamo invece come a JsonRequest lavori.

String url = "http://httpbin.org/get?site=code&network=tutsplus"; JsonObjectRequest jsonRequest = new JsonObjectRequest (Request.Method.GET, url, null, new Response.Listener() @Override public void onResponse (risposta JSONObject) // la risposta è già costruita come JSONObject! prova response = response.getJSONObject ("args"); String site = response.getString ("sito"), network = response.getString ("network"); System.out.println ("Sito:" + sito + "\ nNetwork:" + rete);  catch (JSONException e) e.printStackTrace (); , new Response.ErrorListener () @Override public void onErrorResponse (VolleyError error) error.printStackTrace (); ); Volley.newRequestQueue (questo) .add (jsonRequest);

Bellissimo. Non è vero? Come puoi vedere, il tipo di risultato è già impostato su JSONObject. Puoi chiedere a JSONArray anche se vuoi, usando a JsonArrayRequest invece di a JsonObjectRequest.

Come prima, il primo parametro del costruttore è il metodo HTTP da utilizzare. Quindi fornire l'URL per recuperare il JSON da. La terza variabile nell'esempio sopra è nullo. Questo va bene in quanto indica che nessun parametro verrà pubblicato insieme alla richiesta. Infine, hai l'ascoltatore per ricevere la risposta JSON e un listener di errori. Puoi passare nullo se vuoi ignorare gli errori.

Il recupero delle immagini richiede un po 'più di lavoro. Esistono tre metodi possibili per richiedere un'immagine. ImageRequestè quello standard Visualizza l'immagine richiesta in un comune ImageView, recuperandolo tramite un URL fornito. Tutte le operazioni di decodifica e ridimensionamento che potreste volere che Volley esegua si verificano su un thread di lavoro. La seconda opzione è il ImageLoader classe, che puoi pensare come un orchestratore di un gran numero di ImageRequests, per esempio, per popolare a Visualizzazione elenco con le immagini. La terza opzione è NetworkImageView, che è una sorta di sostituto XML per il ImageView elemento di layout.

Diamo un'occhiata a un esempio.

String url = "http://i.imgur.com/Nwk25LA.jpg"; mImageView = (ImageView) findViewById (R.id.image); ImageRequest imgRequest = new ImageRequest (url, new Response.Listener() @Override public void onResponse (risposta bitmap) mImageView.setImageBitmap (response); , 0, 0, ImageView.ScaleType.FIT_XY, Bitmap.Config.ARGB_8888, new Response.ErrorListener () @Override public void onErrorResponse (Errore VolleyError) mImageView.setBackgroundColor (Color.parseColor ("# ff0000"))) ; error.printStackTrace (); ); Volley.newRequestQueue (questo) .add (imgRequest);

Il primo parametro è l'URL dell'immagine e il secondo è l'ascoltatore per il risultato. Il terzo e il quarto parametro sono numeri interi, larghezza massimaaltezza massima. Puoi impostarli su 0 ignorare questi parametri. Dopo di che, ImageRequestti chiede il ScaleType utilizzato per calcolare la dimensione dell'immagine necessaria e per il formato per la decodifica della bitmap. Suggerisco sempre di usare Bitmap.Config.ARGB_8888. Infine, passiamo in un listener di errori.

Si noti che Volley imposta automaticamente la priorità di questa richiesta a BASSO.

// Snippet tratto da ImageRequest.java, // nel codice sorgente di Volley @Override public Priority getPriority () return Priority.LOW; 

Fare una richiesta POST

Passare da una richiesta GET a una richiesta POST è semplice. Devi cambiare il request.method nel costruttore della richiesta e sovrascrivere il getparams metodo, restituendo un corretto Carta geografica contenente i parametri della richiesta.

String url = "http://httpbin.org/post"; StringRequest postRequest = new StringRequest (Request.Method.POST, url, new Response.Listener() @Override public void onResponse (String response) try JSONObject jsonResponse = new JSONObject (response) .getJSONObject ("form"); String site = jsonResponse.getString ("site"), network = jsonResponse.getString ("network"); System.out.println ("Sito:" + sito + "\ nNetwork:" + rete);  catch (JSONException e) e.printStackTrace (); , new Response.ErrorListener () @Override public void onErrorResponse (VolleyError error) error.printStackTrace (); ) @Override Mappa protetta getParams () Mappa params = new HashMap <> (); // i parametri POST: params.put ("site", "code"); params.put ("network", "tutsplus"); restituire parametri; ; Volley.newRequestQueue (questo) .add (postRequest);

Annullamento di una richiesta

Se si desidera annullare tutte le richieste, aggiungere il seguente frammento di codice al file onStop metodo:

@Override protected void onStop () super.onStop (); mRequestQueue.cancelAll (new RequestQueue.RequestFilter () @ Override public boolean apply (Request richiesta) // devo cancellare questo? ritorna vero; // -> sempre sì); 

In questo modo, non è necessario preoccuparsi della possibilità che l'utente abbia già distrutto l'attività quando onResponse è chiamato. UN NullPointerException sarebbe gettato in tal caso.

Le richieste POST e PUT, tuttavia, dovrebbero continuare anche dopo che l'utente ha modificato le attività. Possiamo realizzare questo usando tag. Quando costruisci una richiesta GET, aggiungi un tag ad essa.

// dopo aver dichiarato la richiesta request.setTag ("GET"); mRequestQueue.add (richiesta);

Per annullare tutte le richieste GET in sospeso, aggiungiamo semplicemente la seguente riga di codice:

mRequestQueue.cancelAll ( "GET");

In questo modo, annulli solo le richieste GET, lasciando intatte altre richieste. Nota che ora devi gestire manualmente il caso in cui l'attività viene distrutta prematuramente.

Gestione dei cookie e priorità delle richieste

Volley non fornisce un metodo per impostare i cookie di una richiesta, né la sua priorità. Probabilmente lo farà in futuro, dal momento che è un'omissione grave. Per il momento, tuttavia, devi estendere il Richiesta classe.

Per gestire i cookie, puoi giocare con le intestazioni della richiesta, ignorando il getHeaders metodo:

public class CustomRequest estende JsonObjectRequest // Poiché stiamo estendendo una classe Request // usiamo solo il suo costruttore public CustomRequest (metodo int, string URL, JSONObject jsonRequest, Response.Listener listener, Response.ErrorListener errorListener) super (metodo, url, jsonRequest, listener, errorListener);  Mappa privata headers = new HashMap <> (); / ** * Classe personalizzata! * / public void setCookies (Elenco cookie) StringBuilder sb = new StringBuilder (); per (String cookie: cookie) sb.append (cookie) .append (";");  headers.put ("Cookie", sb.toString ());  @Override mappa pubblica getHeaders () genera AuthFailureError return headers; 

Con questa implementazione, è possibile fornire direttamente l'elenco di cookie alla richiesta utilizzando setCookies.

// In primo luogo, crei l'elenco dei cookie, // conforme alle convenzioni HTTP // i.e. key = value List cookies = new ArrayList <> (); cookies.add ( "sito = codice"); cookies.add ( "rete = tutsplus"); // quindi invochi il tuo metodo personalizzato customRequest.setCookies (cookie); // e infine aggiunge la richiesta alla coda Volley.newRequestQueue (this) .add (customRequest);

Per la priorità, è anche necessario estendere il Richiesta classe, ignorando il getPriority metodo. Ecco come potrebbe essere l'implementazione:

Priorità mPriority; public void setPriority (Priorità prioritaria) mPriority = priority;  @Override public Priority getPriority () // Se non si è utilizzato il metodo setPriority, // la priorità viene automaticamente impostata su NORMAL restituisce mPriority! = Null? mPriority: Priority.NORMAL; 

Quindi, sul thread principale, richiamare questa riga di codice per impostare la priorità della richiesta:

customRequest.setPriority (Priority.HIGH);

È possibile scegliere tra uno dei quattro possibili stati di priorità come mostrato di seguito:

Priority.LOW // images, thumbnails, ... Priority.NORMAL // residual Priority.HIGH // descrizioni, elenchi, ... Priority.IMMEDIATE // login, logout, ... 

Conclusione

In questo articolo, abbiamo esaminato come funziona la libreria di rete di Volley. Abbiamo visto per la prima volta perché e quando è meglio usare Volley al posto di un'altra soluzione già inclusa nell'SDK di Android. Ci siamo quindi immersi nei dettagli della biblioteca, esaminando il suo flusso di lavoro e i suoi tipi di richiesta supportati. Infine, ci siamo sporcati le mani creando richieste semplici e implementando quelle personalizzate per la gestione dei cookie e la definizione delle priorità.

Nella prossima parte di questa serie su Volley, creeremo una semplice applicazione che sfrutta Volley. Ti mostrerò come creare un'applicazione meteo per Marte, utilizzando i dati meteo raccolti su Marte dal rover Curiosity.

Se fai molto sviluppo su Android, perché non accelera il tuo flusso di lavoro utilizzando uno dei migliaia di utili modelli di app Android disponibili su Envato Market? Oppure contatta uno degli sviluppatori Android su Envato Studio per aiutarti con il tuo progetto: possono perfino progettare la tua app per te da zero!