Dacă sunteți un dezvoltator Android, este posibil să fi auzit lucruri bune despre RxJava, o populară implementare open-source a bibliotecii ReactiveX care aduce programare reactivă la Java Virtual Machine (JVM).
RxJava este conceput pentru a lua durerea de a lucra cu fluxuri asincrone de date - deși așa cum veți vedea, definiția lui RxJava de "date" este destul de largă. Deoarece RxJava este o bibliotecă compatibilă cu JVM, o puteți folosi pe o gamă largă de platforme, dar în această serie vă voi arăta cum să utilizați RxJava 2 pentru dezvoltarea Android.
Până la sfârșitul acestei serii, veți fi masterat toate elementele esențiale RxJava 2, astfel încât să puteți începe să creați aplicații extrem de reactive care pot procesa o gamă largă de date sincrone și asincrone - toate folosind un cod mai concis și mai ușor de gestionat decât ați fi de obicei capabil să realizeze numai cu Java.
În plus față de oferirea unei introduceri pentru nou-veniții RxJava, dacă sunteți un veteran RxJava 1 care caută să facă saltul la RxJava 2, atunci această serie va contribui la transformarea acestei tranziții cât mai netedă. În timp ce actualizarea la cea mai recentă versiune a unei biblioteci ar putea să nu pară o afacere mare, RxJava 2 nu este actualizarea ta tipică - este o rescriere completă a RxJava. Cu o schimbare atât de mare este ușor de confuz, așa că a lua ceva timp să vă familiarizați cu RxJava 2 din perspectiva unui începător ar putea să vă economisească mult timp și frustrare pe termen lung.
În acest prim post, voi acoperi ceea ce este RxJava și beneficiile cheie pe care le oferă dezvoltatorilor Android. De asemenea, vom analiza în profunzime componentele de bază ale site-ului orice Proiectul RxJava: observatorii
, observabilelor
, și abonamente. Până la sfârșitul acestui tutorial, veți fi creat o aplicație simplă "Hello World" care include toate aceste componente de bază.
Celelalte componente importante ale RxJava sunt operatorii, astfel că în partea a doua vom explora diferitele moduri în care puteți utiliza operatorii pentru a transforma, combina, filtra și manipula datele aplicației.
În ultima tranșă, vom trece dincolo de biblioteca RxJava de bază și aruncăm o privire la RxAndroid, o întreagă bibliotecă care este plină cu toate extensiile specifice Android care va trebui să deblocați întregul potențial de programare reactivă pentru Android.
Avem multe de acoperit, așa că să începem cu cele mai importante lucruri:
RxJava este o bibliotecă care vă permite să creați aplicații în stilul de programare reactiv. La bază, programarea reactivă oferă o modalitate curată și eficientă de procesare și reacționare la fluxurile de date în timp real, inclusiv date cu valori dinamice.
Aceste fluxuri de date nu sunt neapărat avea pentru a lua forma unor tipuri de date tradiționale, deoarece RxJava trăiește destul de mult ca un flux de date - totul, de la variabile la proprietăți, cache-uri și chiar evenimente de intrare de la utilizatori, cum ar fi clicurile și swipes.
Datele emise de fiecare flux pot fi fie o valoare, o eroare sau un semnal "finalizat", deși nu trebuie neapărat să implementați ultimele două. Odată ce ați creat fluxurile de date care le transmit, le combinați cu obiecte reactive care consumă și apoi acționează asupra acestor date, efectuând diferite acțiuni în funcție de fluxul emis de flux. RxJava include o grămadă de operatori utili pentru a lucra cu fluxuri, făcându-se ușor să facă lucruri precum filtrarea, maparea, întârzierea, numărarea și multe altele.
Pentru a crea acest flux de fluxuri de date și obiecte care reacționează la ele, RxJava extinde modelul de design al software-ului Observer. În esență, în RxJava ai Observabil
obiecte care emit un flux de date și apoi se termină și Observator
obiecte care se aboneaza la Observabil
s. Un Observator
primește o notificare de fiecare dată când îi sunt atribuite Observabil
emite o valoare, o eroare sau un semnal complet.
Deci, la un nivel foarte înalt, RxJava este vorba despre:
Observabil
.Observabil
unele date de emisie.Observator
.Observator
la un Observabil
.Observator
sarcini de efectuat ori de câte ori primește o emisie din partea sa atribuită Observabil
.Învățând orice tehnologie nouă necesită timp și efort și, ca bibliotecă orientată spre date, RxJava nu este întotdeauna cea mai ușoară API pentru a face față.
Pentru a vă ajuta să decideți dacă învățarea RxJava merită investiția inițială, să explorăm câteva dintre beneficiile cheie ale adăugării bibliotecii RxJava la proiectele Android.
Cod care este complex, verbos și greu de citit este mereu vesti proaste. Codul murdar este mai predispus la erori și alte ineficiențe, iar dacă apar erori, atunci veți avea un timp mult mai dur de urmărire a sursei acestor erori dacă codul dvs. este un dezastru.
Chiar dacă proiectul dvs. se construiește fără erori, codul complex poate să vină în continuare să vă bântuie - de obicei când decideți să lansați o actualizare a aplicației dvs. cu câteva luni în jos, lansați-vă proiectul și vă confruntați imediat cu un perete de cod încurcat, confuz!
RxJava simplifică codul necesar pentru gestionarea datelor și evenimentelor, permițându-vă să descrieți ceea ce doriți să obțineți, mai degrabă decât să scrieți o listă de instrucțiuni pentru ca aplicația dvs. să lucreze. RxJava oferă, de asemenea, un flux de lucru standard pe care îl puteți utiliza pentru a gestiona toate datele și evenimentele din aplicația dvs. - creați un Observabil
, creaza un Observator
, atribuiți observabilului observatorului, clătiți și repetați. Această abordare formală face pentru un cod foarte simplu, ușor de citit de om.
Aplicațiile Android moderne trebuie să fie capabile să facă mai multe sarcini. Cel puțin, utilizatorii dvs. se așteaptă să poată continua să interacționeze cu interfața de utilizare a aplicației dvs. în timp ce aplicația dvs. efectuează anumite activități în fundal, cum ar fi gestionarea unei conexiuni în rețea, descărcarea unui fișier sau redarea muzicii. Problema este că Android are un singur thread în mod implicit, așa că dacă aplicația dvs. va merge vreodată la multi-task cu succes, atunci va trebui să creați câteva fire suplimentare.
În afara căsuței, Android oferă o serie de moduri de a crea fire suplimentare, cum ar fi serviciile și serviciile IntentServices
, dar niciuna dintre aceste soluții nu este deosebit de ușor de implementat și poate duce rapid la un cod complicat, verbos care este predispus la erori.
RxJava își propune să obțină durerea de a crea aplicații Android cu mai multe fire, oferind programatori și operatori speciali. Acestea vă oferă o modalitate ușoară de a specifica firul în care trebuie să se lucreze și firul în care să fie afișate rezultatele acestei lucrări. RxJava 2.0 include un număr de planificatori implicit, inclusiv Schedulers.newThread
, care este în special utilă deoarece creează un fir nou.
Pentru a schimba firul unde se efectuează munca, trebuie doar să schimbați unde un observator se abonează la un observator, folosind subscribeOn
operator. De exemplu, aici creați un fir nou și precizați că lucrarea ar trebui să fie efectuată pe acest thread nou:
observable.subscribeOn (Schedulers.newThread ())
O altă problemă de lungă durată cu multithreading pe Android este că puteți să actualizați interfața UI a aplicației doar din firul principal. De obicei, ori de câte ori trebuie să publicați rezultatele unor lucrări de fundal în UI-ul aplicației, trebuie să creați un program dedicat manipulant
.
Încă o dată, RxJava are o soluție mult mai simplă. Puteți utiliza funcția observeOn
operator pentru a specifica faptul că o persoană observabilă ar trebui să trimită notificările folosind un programator diferit, care vă permite, în esență, să trimiteți datele observabile către firul ales de dvs., inclusiv firul principal al interfeței utilizator.
Acest lucru înseamnă că, cu doar două rânduri de cod, puteți crea un fir nou și puteți trimite rezultatele lucrărilor efectuate pe acest thread la firul principal de interfață cu aplicația Android:
.subscribeOn (Schedulers.newThread ()) .observeOn (AndroidSchedulers.mainThread ())
Bine, deci tehnic noi inselim un pic aici AndroidSchedulers.mainThread
este disponibilă doar ca parte a bibliotecii RxAndroid, pe care nu o vom privi până în partea a treia. Cu toate acestea, acest exemplu vă oferă o privire asupra puterii RxJava și RxAndroid pentru a simplifica o zonă de dezvoltare Android cunoscută ca fiind prea complicată.
Observatorii emit datele într-un mod care ascunde complet modul în care au fost create datele. Din moment ce observatorii dvs. nu văd nici măcar modul în care au fost create datele, sunteți liber să vă implementați Observabil
în orice fel doriți.
Odată ce ați implementat dvs. Observabil
s, RxJava oferă o gamă largă de operatori pe care îi puteți utiliza pentru a filtra, îmbina și transforma datele emise de acestea Observabil
s. Puteți chiar să alăturați mai mulți operatori împreună până când veți crea exact fluxul de date de care are nevoie aplicația dvs..
De exemplu, puteți combina datele din mai multe fluxuri, puteți filtra fluxul nou îmbinat și apoi utilizați datele rezultate ca intrări pentru un flux de date ulterior. Și amintiți-vă că în RxJava totul este tratat ca un flux de date, astfel încât să puteți aplica chiar și acești operatori la "date" netradiționale, cum ar fi evenimentele clic.
Au dispărut zilele în care o aplicație ar putea să scape cu încărcarea unei pagini de conținut și apoi să aștepte ca utilizatorul să atingă Următor → buton. Astăzi, aplicația dvs. mobilă tipică trebuie să fie capabilă să reacționeze la o varietate din ce în ce mai variată de evenimente și date, în mod ideal în timp real. De exemplu, aplicația dvs. tipică pentru rețele sociale trebuie să asculte în permanență plăceri, comentarii și solicitări de prietenie, gestionând în același timp o conexiune de rețea în fundal și răspunzând imediat ori de câte ori utilizatorul întrerupe sau derulează ecranul.
Biblioteca RxJava a fost concepută pentru a putea gestiona o gamă largă de date și evenimente simultan și în timp real, făcându-l un instrument puternic pentru crearea unor tipuri de aplicații extrem de receptive pe care le așteaptă utilizatorii mobili moderni.
Dacă ați decis că RxJava are ceva de oferit pentru a vă dezvolta practica Android, atunci primul pas pentru a deveni un master RxJava este adăugarea bibliotecii la proiectul dvs..
Creați un nou proiect Android Studio cu setările alese de dvs., apoi deschideți modulul la nivel build.gradle fișier și adăugați cea mai recentă versiune de io.reactivex.rxjava2: rxjava
ca dependență.
La momentul redactării, RxJava 2.0.5 a fost cea mai recentă versiune, așa că eu build.gradle fișierul arată astfel:
dependență compile fileTree (dir: 'libs', include: ['* .jar']) androidTestCompile ('com.android.support.test.espresso: espresso-core: 2.2.2', exclude grup: android.support ', modul:' support-adnotations ') compilați' com.android.support:appcompat-v7:25.1.0 'testCompile' junit: junit: 4.12 'compile' io.reactivex.rxjava2: rxjava: 2.0. 5 '
Când vi se solicită, faceți clic pe Sincronizați acum.
Apoi, deschide-ți Activitate principala
fișierul și adăugați importurile de care aveți nevoie pentru a începe să lucrați cu caracteristicile RxJava de bază:
import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import io.reactivex.ObservableOnSubscribe; import io.reactivex.Observer; import io.reactivex.disposables.Disposable;
Dacă migrați din RxJava 1, atunci aceste importuri s-ar putea să nu fie ceea ce vă așteptați, deoarece RxJava 1 a folosit un nume de pachet complet diferit (rx
pentru a fi precis).
Cu toate acestea, aceasta nu este o schimbare a numelui arbitrar: numele diferitelor pachete vă oferă opțiunea de a utiliza RxJava 1 și RxJava 2 unul lângă celălalt în același proiect. Dacă sunteți la jumătatea unui proiect care utilizează RxJava 1, puteți adăuga biblioteca RxJava 2 și începeți să utilizați imediat cele 2 funcții actualizate, fără a întrerupe codul RxJava 1.
Dacă începeți călătoria RxJava cu versiunea 2, atunci trebuie doar să știți că dacă întâlniți orice tutoriale RxJava sau un cod utilizând rx
numele pachetului, atunci acesta este codul RxJava 1 și este puțin probabil să fie compatibil cu biblioteca versiune 2.
Până acum, am privit doar la RxJava la un nivel foarte înalt. Este timpul să vă familiarizați mai mult și să examinați în profunzime două dintre cele mai importante componente care vor apărea din timp și din nou pe tot parcursul lucrării dvs. RxJava: Observator
și Observabil
s.
Până la sfârșitul acestei secțiuni, nu numai că veți avea o înțelegere solidă a acestor două componente principale, dar veți fi creat o aplicație pe deplin funcțională care constă într-o Observabil
care emite date și o Observator
care reacționează la aceste emisii.
Observabil
Un Observabil
este similar cu un Iterable
prin faptul că, dat fiind o secvență, va trece prin secvența respectivă și va emite fiecare element, deși Observabil
În mod normal, nu începeți să emiteți date până la data de Observator
le subscrie.
De fiecare dată când Observabil
emite un element, acesta notifică atribuirea acestuia Observator
folosind onNext ()
metodă. O dată Observabil
a transmis toate valorile sale, se termină apelând fie:
onComplete
: Numit dacă operația a avut succes. onerror
: Numit dacă o Excepție
a fost aruncat.Să ne uităm la un exemplu. Aici, creăm un Observator care emite numerele 1, 2, 3 și 4, și apoi se termină.
Observabilobservable = Obsable.create (new ObservableOnSubscribe () @Override public void subscribe (ObservableEmitter e) aruncă Excepție // Utilizați onNext pentru a emite fiecare element în fluxul // e.onNext (1); e.onNext (2); e.onNext (3); e.onNext (4); // Odată ce Observatorul a emis toate elementele din secvență, apelați peComplete // e.onComplete (); );
Rețineți că, în acest exemplu, scriu exact ce se întâmplă, deci nu lăsați cantitatea de cod să vă scape! Acesta este un cod mult mai mare decât cel pe care îl veți folosi de obicei pentru a crea Observabil
în proiectele dvs. RxJava din viața reală.
Observator
s sunt obiecte pe care le atribui unui Observabil
, folosind Abonati-va()
operator. O dată Observator
este abonat la un Observabil
, va reacționa ori de câte ori este Observator
emit unul dintre următoarele:
onNext
: a Observabil
a emis o valoare.onerror
: A avut loc o eroare.onComplete
: a Observabil
a terminat să emită toate valorile.Să creăm un Observator
care este abonat la noastre 1, 2, 3, 4 Observabil
. Pentru a ajuta la menținerea lucrurilor simple, acest lucru Observator
va reacționa la onNext
, onerror
și onComplete
prin imprimarea unui mesaj către Android Studio Logcat Monitor:
Observatorobservator = observator nou () @Override public void onSubscribe (Disponibil d) Log.e (TAG, "onSubscribe:"); @Override public void onNext (valoarea întregului) Log.e (TAG, "onNext:" + valoare); @Override publice void onError (Throwable e) Log.e (TAG, "onError:"); @Override public void onComplete () Log.e (TAG, "onComplete: All Done!"); ; // Creați abonamentul nostru // observable.subscribe (observator);
Deschideți Monitorul Logcat al aplicației Android Studio selectând Android Monitor din partea de jos a ferestrei Android Studio (unde cursorul este poziționat în imaginea de mai jos) și selectând apoi logcat fila.
Pentru a pune acest cod la încercare, fie atașați dispozitivul fizic Android la mașina dvs. de dezvoltare, fie executați proiectul pe un AVD compatibil. De îndată ce aplicația dvs. apare pe ecran, ar trebui să vedeți datele emise de observabil.
Deși proiectul nostru emit date cu succes, codul pe care îl folosim nu este exact concis - în special codul pe care îl folosim pentru a ne crea Observabil
.
Din fericire, RxJava oferă o serie de metode de confort care vă permit să creați un Observabil
folosind codul mult mai puțin:
Puteți utiliza funcția .doar()
operator pentru a converti orice obiect într-un Observabil
. Rezultatul Observabil
va emite obiectul original și va fi finalizat.
De exemplu, aici creăm un Observabil
care va emite un singur șir la toate ei observatorii
:
Observabilobservable = Observable.just ("Hello World!");
Observable.from ()
.din()
operator vă permite să convertiți o colecție de obiecte într-un flux observabil. Puteți converti un matrice într-un Observabil
utilizând Observable.fromArray
, A nevărsat
într-un Observabil
utilizând Observable.fromCallable
, si un Iterable
într-un Observabil
utilizând Observable.fromIterable
.
Observable.range ()
Puteți utiliza funcția .gamă()
operator pentru a emite o serie de numere întregi secvențiale. Primul număr întreg pe care îl furnizați este valoarea inițială, iar al doilea este numărul de numere întregi pe care doriți să îl emiteți. De exemplu:
Observabilobservabilă = observabilă (0, 5);
Observable.interval ()
Acest operator creează un Observabil
care emite o secvență infinită de întregi ascendenți, fiecare emisie fiind separată de un interval de timp ales de dvs. De exemplu:
Observabilobservable = Observ.interval (1, TimeUnit.SECONDS)
Observable.empty ()
gol()
operatorul creează un Observabil
care nu emite nimic, dar se termină în mod normal, ceea ce poate fi util atunci când trebuie să creați rapid un Observabil
pentru scopuri de testare.
Observabilobservable = Observable.empty ();
În acest articol, am acoperit blocurile fundamentale ale RxJava.
În acest moment, știi cum să creezi și să lucrezi cu observatorii
și observabilelor
, și cum să creați un abonament astfel încât dvs. observabilelor
pot începe să emită date. De asemenea, am analizat pe scurt câțiva operatori care vă permit să creați o gamă diferită observabilelor
, folosind codul mult mai puțin.
Cu toate acestea, operatorii nu sunt doar un mod la îndemână de reducere a cantității de cod de care aveți nevoie pentru a scrie! Crearea unui Observator
si un Observabil
este destul de simplu, dar operatorii sunt acolo unde începi cu adevărat să vezi ce este posibil cu RxJava.
Deci, în postul următor, vom explora unii dintre cei mai puternici operatori ai RxJavy, inclusiv operatorii care pot face în cele din urmă multi-threading pe Android o experiență fără durere. Rămâi acordat pentru a afla puterea reală a bibliotecii RxJava.
Între timp, verificați câteva dintre celelalte postări și cursuri despre dezvoltarea Android, aici pe Envato Tuts+!
Diagramele de date observabile sunt din documentația ReactiveX și sunt licențiate sub licența Creative Commons Attribution 3.0 License.