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 novo. Se 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.
HttpURLConnection
e HttpClient
Su livelli API inferiori (principalmente su Gingerbread e Froyo), HttpURLConnection
e HttpClient
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.
AsyncTask
PureDall'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
.
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.
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ò.
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.
Volley funziona su tre diversi livelli con ogni livello che opera su una propria thread.
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.
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.
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.
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 RequestQueue
oggetto invocando uno dei metodi di convenienza di Volley, Volley.newRequestQueue
. Questo imposta a RequestQueue
oggetto, 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.
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 massima
e altezza massima
. Puoi impostarli su 0
ignorare questi parametri. Dopo di che, ImageRequest
ti 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;
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);
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.
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.Listenerlistener, 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 Listcookies = 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, ...
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!