O introducere în volei

Volley este o bibliotecă de rețea creată de Google și introdusă în cadrul Google I / O 2013. A fost dezvoltată din cauza absenței, în Android SDK, a unei clase de rețea capabilă să lucreze fără a interfera cu experiența utilizatorului.

Până la lansarea lui Volley, clasa Java canonică java.net.HttpURLConnection și Apache org.apache.http.client au fost singurele instrumente disponibile programatorilor Android pentru a dezvolta un sistem RESTful între un client și un backend de la distanță.

Anularea pentru o clipă a faptului că aceste două clase nu sunt scutite de bug-uri, trebuie remarcat faptul că tot ce a depășit o simplă tranzacție HTTP a trebuit să fie scris ex novoDacă doriți să cacheți imaginile sau să prioritizați cererile, a trebuit să le dezvoltați de la zero.

Din fericire, acum există Volley, creat și adaptat pentru a îndeplini aceste nevoi.

1. De ce Volley?

Evita HttpUrlConnection și httpclient

La niveluri inferioare API (mai ales pe Gingerbread și Froyo), HttpUrlConnection și httpclient sunt departe de a fi perfecte. Există câteva fragmente cunoscute și bug-uri care nu au fost niciodată rezolvate. în plus, httpclient a fost depreciat în ultima actualizare API (API 22), ceea ce înseamnă că nu va mai fi menținută și poate fi eliminată într-o versiune viitoare.

Acestea sunt motive suficiente pentru a decide să treceți la o modalitate mai fiabilă de a vă gestiona solicitările de rețea.

Și Evitați AsyncTask De asemenea

De la introducerea Honeycomb (API 11), a fost obligatoriu să se efectueze operații de rețea pe un fir separat, diferit de firul principal. Această schimbare substanțială a condus la utilizarea masivă a AsyncTask specificație.

Cu AsyncTask, definiți mai întâi câteva acțiuni pregătitoare, cum ar fi definirea contextului, în onPreExecute. Apoi, efectuați sarcinile asincrone folosind doInBackground metodă. În cele din urmă, gestionați rezultatele onPostExecute. Este destul de simplu, mult mai ușor decât implementarea unui serviciu și vine cu o mulțime de exemple și documentație.

Principala problemă, totuși, este serializarea apelurilor. Utilizarea AsyncTask clasa, nu puteți decide care dintre solicitări merge mai întâi și care trebuie să aștepte. Totul se întâmplă FIFO, mai întâi în primul rând.

Problemele apar, de exemplu, când trebuie să încărcați o listă de articole care au atașat o miniatură. Atunci când utilizatorul scroll în jos și se așteaptă la rezultate noi, nu puteți spune activității dvs. să încărcați mai întâi JSON-ul paginii următoare și numai atunci imaginile din cea anterioară. Acest lucru poate deveni o problemă serioasă de experiență a utilizatorilor în aplicații cum ar fi Facebook sau Twitter, unde lista de elemente noi este mai importantă decât miniaturile asociate cu aceasta.

Volley își propune să rezolve această problemă prin includerea unui puternic API de anulare. Nu mai trebuie să te înregistrezi onPostExecute dacă activitatea a fost distrusă în timpul efectuării apelului. Acest lucru ajută la evitarea unui nedorit NullPointerException.

Este mult mai rapid

Cu ceva timp în urmă, echipa Google+ a efectuat o serie de teste de performanță pe fiecare dintre metodele diferite pe care le puteți utiliza pentru a face cereri de rețea pe Android. Volley a obținut un scor de până la zece ori mai bun decât celelalte alternative când este folosit în aplicațiile RESTful.

Este Caches Totul

Volley automat cache cereri și aceasta este cu adevărat de salvare a vieții. Să revenim pentru un moment la exemplul pe care l-am dat mai devreme. Aveți o listă de elemente - să spuneți o matrice JSON - și fiecare articol are o descriere și o miniatură asociată cu ea. Acum, gândiți-vă la ceea ce se întâmplă dacă utilizatorul rotește ecranul: activitatea este distrusă, lista este descărcată din nou, la fel și imaginile. Povestea scurtă, o pierdere semnificativă de resurse și o experiență slabă a utilizatorului.

Volley se dovedește a fi extrem de util pentru depășirea acestei probleme. Aceasta amintește apelurile anterioare au făcut și gestionează distrugerea și reconstrucția activității. Ea cache totul, fără să vă faceți griji despre asta.

Operații de metadate mici

Volley este perfectăpentru apeluri mici, cum ar fi obiecte JSON, porțiuni de liste, detalii ale unui element selectat și așa mai departe. Acesta a fost conceput pentru aplicații RESTful și, în acest caz special, oferă cele mai bune rezultate.

Cu toate acestea, nu este atât de bun atunci când sunt angajați pentru operațiuni de streaming și descărcări mari. Contrar convingerii comune, numele lui Volley nu vine din dicționarul sportiv. Este vorba mai degrabă de repetări ale apelurilor, grupate împreună. Este ceva intuitiv de ce această bibliotecă nu vine la îndemână atunci când, în loc de un volei de săgeți, vrei să tragi o minge de tun.

2. Sub Hood

Voleiul funcționează pe trei niveluri diferite, fiecare nivel funcționând pe firul propriu.

Subiect principal

Pe firul principal, în mod consecvent cu ceea ce faceți deja în AsyncTask specificare, aveți permisiunea să declanșați solicitarea și să rezolvați răspunsul acesteia. Nimic mai mult, nimic mai puțin.

Principala consecință este că puteți ignora tot ceea ce se întâmplă în doInBackground metodă. Volley gestionează în mod automat tranzacțiile HTTP și erorile din rețeaua de captură de care aveați nevoie să aveți grijă înainte.

Cache și Threads de rețea

Când adăugați o cerere la coadă, mai multe lucruri se întâmplă sub capotă. În primul rând, Volley verifică dacă cererea poate fi întreținută din cache. Dacă este posibil, răspunsul memorat în cache este citit, analizat și livrat. În caz contrar, este trecut la firul de rețea.

Pe firul de rețea, o robinet rotund cu o serie de filete funcționează în mod constant. Primul fir de rețea disponibil elimină cererea, face cererea HTTP, analizează răspunsul și îl scrie în memoria cache. Pentru a termina, trimite răspunsul parsizat înapoi la firul principal în care ascultătorii dvs. așteaptă să se ocupe de rezultat.

3. Noțiuni de bază

Pasul 1: Importarea Volei

Volley nu este atât de la îndemână pentru a înființa. Se pare că nu există un depozit oficial Maven și acest lucru este destul de uimitor. Trebuie să vă bazați pe codul sursă oficial. Puteți importa Volei în una din mai multe moduri.

Mai intai, descarcati sursa Volley din depozit. Dacă vă simțiți încrezător în a face acest lucru, acest Gitcomanda poate face tot munca pentru tine:

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

Până în urmă cu câteva săptămâni, ați putea împacheta totul folosind furnică Linie de comanda (android update project -p . și apoi mistreț de furnică) și importul dvs. BORCAN bibliotecă în proiectul dvs. Android Studio cu o simplă compile fișiere ('libs / volley.jar').

Recent, însă, Google a actualizat volley-ul pentru stilul de construire Android Studio, făcându-l mai greu pentru a crea un standalone BORCAN. Puteți să o faceți, dar numai cu versiuni mai vechi ale bibliotecii. Eu personal vă descurajez să utilizați această opțiune, deși poate părea cea mai rapidă.

Ar trebui să-l aranjezi pe Volley clasic, adică importând sursa ca a modul. În Android Studio, cu proiectul deschis, selectați Fișier> Modul nou, și selectați Importați proiectul existent. Selectați directorul în care tocmai ați descărcat codul sursă și confirmați. Un folder numit Volley va apărea în structura proiectului. Android Studio vă actualizează automat settings.gradle fișier pentru a include modulul Volley, astfel încât trebuie doar să adăugați dependențele dvs. compilați proiectul (': volei') și ați terminat.

Există oa treia cale. Puteți adăuga la secțiunea de dependență din build.gradle trimiteți această linie:

compile 'com.mcxiaoke.volley: bibliotecă-aar: 1.0.15'

Este o copie în oglindă a repozitorului oficial Google, sincronizată și actualizată în mod regulat. Este probabil cel mai simplu și cel mai rapid mod de a începe. Cu toate acestea, fiți conștienți, este un lucru neoficial Reprezentanța Maven, fără garanții și nu este susținută de Google.

După părerea mea, este mai bine să investim încă câteva minute importând codul sursă oficial. În acest fel, puteți să mergeți cu ușurință la definițiile și implementările originale, astfel încât, în caz de îndoială, să vă puteți baza mereu pe sursa oficială de Volley - și chiar să o schimbați dacă aveți nevoie să.

Pasul 2: Folosind Volei

Volley lucrează în majoritate cu doar două clase, RequestQueue și Cerere. Mai întâi creați o RequestQueue, care gestionează firele lucrătorilor și furnizează rezultatele analizate înapoi la firul principal. Apoi, treceți unul sau mai multe Cerere obiecte.

Cerere constructorul ia întotdeauna ca parametri tipul de metodă (GET, POST, etc.), adresa URL a resurselor și ascultătorii de evenimente. Apoi, în funcție de tipul solicitării, poate cere mai multe variabile.

În următorul exemplu, creez a RequestQueueobiect prin invocarea uneia dintre metodele de convenție ale lui Volley, Volley.newRequestQueue. Aceasta stabilește o RequestQueueobiect, folosind valorile implicite definite de Volley.

String url = "http://httpbin.org/html"; // Solicitați un răspuns StringRequest stringRequest = new StringRequest (Request.Method.GET, url, new Response.Listener() @Override public void onResponse (răspunsul șirului) // Rezultatul de manipulare System.out.println (response.substring (0,100)); , noul Response.ErrorListener () @Override public void onErrorResponse (Eroare volleyError) // Eroare la manipularea System.out.println ("Ceva a mers prost!"); error.printStackTrace (); ); // Adăugați cererea în coada Volley.newRequestQueue (aceasta) .add (stringRequest); 

După cum puteți vedea, este incredibil de simplă. Creați solicitarea și adăugați-o în coada de solicitare. Și ați terminat.

Rețineți că sintaxa ascultătorului este similară cu AsyncTask.onPostExecute, pur și simplu devine onResponse. Aceasta nu este o coincidență. Dezvoltatorii care au lucrat la Volley au făcut ca API-ul bibliotecii să fie similar cu cel al lui AsyncTask metode. Aceasta face trecerea de la utilizarea AsyncTask la Volei, mult mai ușor.

Dacă trebuie să trageți mai multe solicitări în mai multe activități, ar trebui să evitați să folosiți abordarea de mai sus, Volley.newRequestQueue.add. Este multmai bine să instanțiați o coadă de solicitări partajate și să o utilizați în cadrul proiectului dvs.:

. MySingletonClass.getInstance () getRequestQueue () se adaugă (myRequest.);

Vom vedea în mod special pentru a dezvolta ceva de genul acesta în următorul tutorial din această serie.

4. Puneți mâinile în aluat

Manipularea cererilor standard

Volley vine la îndemână pentru implementarea a trei tipuri de solicitări foarte frecvente:

  • StringRequest
  • ImageRequest
  • JsonRequest

Fiecare dintre aceste clase extinde Rezultat clasa pe care am folosit-o mai devreme. Ne-am uitat deja la StringRequest în exemplul anterior. Să vedem în schimb cum JsonRequest lucrări.

String url = "http://httpbin.org/get?site=code&network=tutsplus"; JsonObjectRequest jsonRequest = nou JsonObjectRequest (Request.Method.GET, url, null, new Response.Listener() @Override public void onResponse (răspuns JSONObject) // răspunsul este deja construit ca un JSONObject! încercați response = response.getJSONObject ("args"); Site-ul șir = answer.getString ("site"), network = response.getString ("rețea"); System.out.println ("Site:" + site + "\ nNetwork:" + rețea);  captură (JSONException e) e.printStackTrace (); , noul Response.ErrorListener () @Override public void peErrorResponse (eroare eroare VolleyError) error.printStackTrace (); ); Volley.newRequestQueue (aceasta) .add (jsonRequest);

Frumos. Nu-i așa? După cum puteți vedea, tipul de rezultat este deja setat la obiect JSON. Puteți cere un a JSONArray prea dacă vrei, folosind a JsonArrayRequest în loc de a JsonObjectRequest.

Ca și înainte, primul parametru al constructorului este metoda HTTP de utilizat. Apoi, furnizați adresa URL pentru a prelua JSON de la. A treia variabilă din exemplul de mai sus este nul. Acest lucru este bine, deoarece indică faptul că nu vor fi afișați parametri împreună cu cererea. În cele din urmă, aveți ascultătorul să primească răspunsul JSON și un ascultător de eroare. Poți să intri nul dacă doriți să ignorați erorile.

Preluarea imaginilor necesită un pic mai mult de lucru. Există trei metode posibile pentru solicitarea unei imagini. ImageRequesteste cea standard. Afișează imaginea pe care ați cerut-o într-o comună ImageView, preluarea acestuia prin intermediul unei adrese URL furnizate. Toate operațiile de decodificare și redimensionare pe care le-ați putea dori să le îndeplinească Volley pe firul lucrătorului. A doua opțiune este ImageLoader clasa, pe care vă puteți gândi ca un orchestrator al unui număr mare de ImageRequests, de exemplu, pentru a popula a ListView cu imagini. A treia opțiune este NetworkImageView, care este un fel de substitut XML pentru ImageView element de aspect.

Să ne uităm la un exemplu.

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

Primul parametru este adresa URL a imaginii, iar al doilea este ascultătorul rezultatului. Al treilea și al patrulea parametru sunt numere întregi, lățimea maximă și maxHeight. Le puteți seta 0 să ignorați acești parametri. Dupa aceea, ImageRequestte întreabă ScaleType folosit pentru a calcula dimensiunea imaginii necesare și pentru formatul de decodificare a bitmap-ului. Vă sugerez să folosiți mereu Bitmap.Config.ARGB_8888. În cele din urmă, trecem printr-un ascultător de erori.

Rețineți că Volley stabilește automat prioritatea acestei solicitări SCĂZUT.

// Fragment preluat din ImageRequest.java, // în codul sursă Volley @Override public Priority getPriority () return Priority.LOW; 

Efectuarea unei solicitări POST

Trecerea de la o cerere GET la o cerere POST este simplă. Trebuie să schimbați Request.Method în constructorul cererii și suprascrie getParams metodă, returnarea unei proprietăți Hartă conținând parametrii solicitării.

String url = "http://httpbin.org/post"; StringRequest postRequest = nou StringRequest (Request.Method.POST, url, new Response.Listener() @Override public void onResponse (răspunsul șir) try JSONObject jsonResponse = nou JSONObject (răspuns) .getJSONObject ("form"); Site-ul String = jsonResponse.getString ("site"), network = jsonResponse.getString ("rețea"); System.out.println ("Site:" + site + "\ nNetwork:" + rețea);  captură (JSONException e) e.printStackTrace (); , noul Response.ErrorListener () @Override public void peErrorResponse (eroare eroare VolleyError) error.printStackTrace (); ) @Operride protejate Harta getParams () Harta paramuri = nou HashMap <> (); // parametrii POST: params.put ("site", "code"); params.put ("rețea", "tutsplus"); paramă de întoarcere; ; Volley.newRequestQueue (aceasta) .add (postRequest);

Anularea unei solicitări

Dacă doriți să anulați toate solicitările dvs., adăugați în fragmentul de text următorul fragment de cod onStop metodă:

@Override protejate void onStop () super.onStop (); mRequestQueue.cancelAll (new RequestQueue.RequestFilter () @Override public boolean apply (Request cerere) // trebuie să anulez acest lucru? return true; // -> întotdeauna da); 

În acest fel, nu trebuie să vă faceți griji cu privire la posibilitatea ca utilizatorul să fi distrus deja activitatea când onResponse se numește. A NullPointerException ar fi aruncat într-un astfel de caz.

Cererile POST și PUT ar trebui să continue, chiar și după ce utilizatorul schimbă activitățile. Putem realiza acest lucru folosind Etichete. Când construiți o solicitare GET, adăugați o etichetă la ea.

// după declararea cererii dvs. request.setTag ("GET"); mRequestQueue.add (cerere);

Pentru a anula fiecare cerere GET în așteptare, pur și simplu adăugăm următoarea linie de cod:

mRequestQueue.cancelAll ( "GET");

În acest fel, anulați cererile GET, lăsând alte cereri neatinsă. Rețineți că acum trebuie să gestionați manual cazul în care activitatea este distrusă prematur.

Gestionarea cookie-urilor și a priorităților de solicitare

Volley nu oferă o metodă de setare a modulelor cookie ale unei solicitări, nici prioritatea acesteia. Probabil va fi în viitor, deoarece este o omisiune gravă. Cu toate acestea, pentru moment, trebuie să extindeți Cerere clasă.

Pentru gestionarea cookie-urilor, puteți să jucați cu anteturile cererii, înlăturând getHeaders metodă:

clasa publica CustomRequest extinde JsonObjectRequest // Deoarece extindem o clasa Request // folosim doar constructorul public CustomRequest (metoda int, String url, JSONObject jsonRequest, Response.Listener ascultător, eroare Response.ErrorListenerListener) super (metoda, url, jsonRequest, ascultător, errorListener);  Harta privată headers = nou HashMap <> (); / ** * Clasa particularizată! * / public void setCookies (Listă cookie-uri) StringBuilder sb = new StringBuilder (); pentru (cookie-ul de caractere: cookie-uri) sb.append (cookie) .append (";");  headers.put ("Cookie", sb.toString ());  @Override hartă publică getHeaders () aruncă AuthFailureError return headers; 

Cu această implementare, puteți furniza direct lista de module cookie la cerere folosind setCookies.

// În primul rând, creați lista cookie-urilor, // conforme cu convențiile HTTP // adică key = value List cookies = noul ArrayList <> (); cookies.add ( "site = cod"); cookies.add ( "rețea = tutsplus"); // apoi invocați metoda CustomRequest.setCookies (cookie-uri); // și adăugați în final cererea la coadă Volley.newRequestQueue (this) .add (customRequest);

Pentru prioritate, trebuie să extindeți Cerere clasa, suprascriind getPriority metodă. Aceasta ar putea arăta implementarea:

Prioritate m; set de priorități publice prioritare mPriority = priority;  @Override public Priority getPriority () // Dacă nu ați utilizat metoda setPriority, // prioritatea este setată automat la revenire NORMAL mPriority! = Null? mPrioritate: Prioritate.NORMAL; 

Apoi, pe firul principal, invocați această linie de cod pentru a seta prioritatea solicitării:

customRequest.setPriority (Priority.HIGH);

Puteți alege una dintre cele patru stări prioritare posibile, după cum se arată mai jos:

Priority.LOW // imagini, miniaturi, ... Priority.NORMAL // reziduale Priority.HIGH // descrieri, liste, ... Priority.IMMEDIATE // login, logout, ... 

Concluzie

În acest articol, ne-am uitat la cum funcționează biblioteca de rețele Volley. Am văzut mai întâi de ce și când este mai bine să folosiți Volley în loc de altă soluție deja inclusă în Android SDK. Apoi am adâncit detaliile bibliotecii, privind fluxul de lucru și tipurile de solicitare acceptate. În sfârșit, am murdărit mâinile prin crearea unor cereri simple și prin implementarea celor personalizate pentru manipularea cookie-urilor și prioritizarea acestora.

În următoarea parte a acestei serii despre Volley, vom crea o aplicație simplă care folosește Volley. Îți arăt cum să faci o aplicație meteorologică pentru Marte, folosind date despre vreme colectate pe Marte de către Curiozitate.

Dacă faceți o mulțime de dezvoltare Android, de ce să nu accelerați fluxul de lucru utilizând una din mii de șabloane utile de aplicații Android disponibile pe Envato Market? Sau contactați unul dintre dezvoltatorii Android de pe Envato Studio pentru a vă ajuta în proiectul dvs. - ei pot chiar să vă proiecteze aplicația de la început!

Cod