Noțiuni de bază cu ReactiveX pe Android

Introducere

Dezvoltarea unei aplicații complexe Android care are o mulțime de conexiuni de rețea, interacțiuni cu utilizatorul și animații înseamnă adesea scrierea unui cod care este plin de apelări inversate. Un astfel de cod, uneori numit callback iad, nu este doar lungă și greu de înțeles, ci și predispusă la erori. ReactiveX oferă o abordare alternativă care este clară și concisă, pentru a gestiona sarcinile și evenimentele asincrone.

RxJava este o implementare JVM a ReactiveX, dezvoltată de NetFlix, și este foarte populară printre dezvoltatorii Java. În acest tutorial, veți învăța cum să utilizați legăturile RxJava pentru Android, sau RxAndroid pe scurt, în proiectele Android.

1. Configurarea RxAndroid

Pentru a utiliza RxAndroid într-un proiect Android Studio, adăugați-l ca un compila dependență în modulul aplicației build.gradle.

java compile 'io.reactivex: rxandroid: 0.25.0'

2. Bazele observatorilor și observatorilor

Când lucrați cu ReactiveX, veți folosi pe larg observatori și observatori. Vă puteți gândi la un obiect observabil ca un obiect care emite date și un observator ca obiect care consumă aceste date. În RxJava și RxAndroid, observatorii sunt instanțe ale Observator interfața și observabilele sunt exemple ale Observabil clasă.

Observabil clasa are numeroase metode statice operatori, a crea Observabil obiecte. Următorul cod vă arată cum să utilizați doar operator pentru a crea o foarte simplă Observabil care emite un singur Şir.

java observabil myObservable = Observable.just ("Hello"); // emite "Bună ziua"

Observația pe care tocmai am creat-o va emite datele numai atunci când are cel puțin un observator. Pentru a crea un observator, creați o clasă care implementează Observator interfață. Observator interfața a denumit intuitiv metode pentru a gestiona diferitele tipuri de notificări pe care le poate primi de la observabile. Iată un observator care poate imprima Şir emise de observabilul pe care l-am creat mai devreme:

"observator java myObserver = Observer nou() @Override public void onCompleted () // Chemat când observabilul nu mai are date de emisie

@Override public void onError (Throwable e) // Numit atunci când observabilul întâlnește o eroare @Override public void onNext (String s) // Chemat de fiecare dată când observabilul emite date Log.d ("OBSERVER MY, s) ; ; "

Pentru a atribui un observator observatorului, ar trebui să îl utilizați Abonati-va , care returnează a Abonament obiect. Se face următorul cod myObserver observa myObservable:

java Abonament mySubscription = myObservable.subscribe (myObserver);

De îndată ce un observator este adăugat observatorului, acesta emite datele sale. Prin urmare, dacă executați codul acum, veți vedea Salut tipărite în aplicația Android Studio logcat fereastră.

S-ar putea să fi observat că nu am folosit-o onCompleted si onerror metode în myObserver. Deoarece aceste metode sunt adesea lăsate neutilizate, aveți, de asemenea, opțiunea de a utiliza Acțiunea 1 care conține o singură metodă numită apel.

java Acțiune1 myAction = acțiune nouă1() @Override apel public void (String s) Log.d ("Acțiunea mea", s); ;

Când treci o instanță de Acțiunea 1 la Abonati-va metodă, apel metoda este invocată ori de câte ori observabilul emite date.

java Abonament mySubscription = myObservable.subscribe (myAction1);

Pentru a detașa un observator de observabil, în timp ce observabilul emit încă date, puteți apela de dezabonare metoda pe Abonament obiect.

java mySubscription.unsubscribe ();

3. Utilizarea operatorilor

Acum că știți cum să creați observatori și observatori, permiteți-mi să vă arăt cum să utilizați operatorii ReactiveX care pot crea, transforma și efectua alte operații pe observabile. Să începem prin crearea unui ușor mai avansat Observabil, unul care emite elemente dintr-o serie de Întreg obiecte. Pentru a face acest lucru, trebuie să utilizați din operator, care poate genera un Observabil din matrice și liste.

"java observabil myArrayObservable = Observabil.de (noul Integer [] 1, 2, 3, 4, 5, 6); // Emite fiecare element al matricei, unul câte unul

myArrayObservable.subscribe (noua acțiune1() @Override apel public void (Integer i) Log.d ("Acțiunea mea", String.valueOf (i)); // Tipărește numărul primit); "

Când executați acest cod, veți vedea fiecare dintre numerele matricei tipărite una după alta.

Dacă sunteți familiarizat cu JavaScript, Ruby sau Kotlin, ați putea fi familiarizați cu funcții de ordin superior, cum ar fi Hartă și filtru, care pot fi folosite la lucrul cu matrice. ReactiveX are operatori care pot efectua operații similare pe observabile. Cu toate acestea, deoarece Java 7 nu are funcții lambda și de ordin superior, va trebui să o facem cu clase care simulează lambda. Pentru a simula o lambda care are nevoie de un argument, va trebui să creați o clasă care să implementeze func1 interfață.

Iată cum puteți utiliza Hartă operator pentru a pătrat fiecare element de myArrayObservable:

java myArrayObservable = myArrayObservable.map (noul Func1() // Intrarea și ieșirea sunt ambele Integer @Override public Integer call (Integer întreg) retur integer * integer; // Pătrundeți numărul);

Rețineți că apelul către Hartă operatorul returnează un nou Observabil, nu schimba originalul Observabil. Dacă vă abonați myArrayObservable acum, veți primi pătrate ale numerelor.

Operatorii pot fi înlănțuiți. De exemplu, următorul bloc de cod utilizează ocolire operator pentru a sări peste primele două numere și apoi filtru operator pentru a ignora numerele impare:

"java myArrayObservable .skip (2) // Sari peste primele două elemente .filter (noul Func1() @Override apel public Boolean (integer întreg) // Ignoră orice element care returnează interogarea returnată false% 2 == 0; );

// Emiși 4 și 6 "

4. Manipularea locurilor de muncă asincrone

Observatorii și observatorii pe care i-am creat în secțiunile anterioare au lucrat pe un singur fir, firul de interfață cu Android. În această secțiune, vă voi arăta cum să utilizați ReactiveX pentru a gestiona mai multe fire și cum ReactiveX rezolvă problema cheii de apel invers.

Să presupunem că aveți o metodă numită fetchData care poate fi folosit pentru a prelua datele dintr-un API. Să presupunem că acceptă o adresă URL ca parametru și returnează conținutul răspunsului ca a Şir. Următorul fragment de cod arată cum ar putea fi utilizat.

java Conținut de caractere = fetchData ("http://www.google.com"); // returneaza continutul google.com ca si String

Această metodă trebuie să ruleze pe firul propriu, deoarece Android nu permite operațiuni de rețea pe firul UI. Aceasta înseamnă că veți crea fie un AsyncTask sau creați un Fir care folosește a manipulant.

Cu ReactiveX, cu toate acestea, aveți oa treia opțiune care este puțin mai concisă. Utilizarea subscribeOn și observeOn operatori, puteți specifica în mod explicit ce fir trebuie să execute lucrarea de fundal și care fir trebuie să se ocupe de actualizările interfeței de utilizator.

Următorul cod creează un personalizat Observabil folosind crea operator. Când creați un Observabil în acest fel, trebuie să implementați Observable.OnSubscribe interfața și controlați ceea ce emite apelând onNext, onerror, și onCompleted vă însuțiți.

java observabil fetchFromGoogle = Obsable.create (new Observable.OnSubscribe() @Override public void call (Abonat abonat) try String data = fetchData ("http://www.google.com"); subscriber.onNext (date); // Emiteți conținutul abonatului URL.onCompletată (); // Nu mai emit nimic captură (Excepție e) subscriber.onError (e); // În cazul în care există erori de rețea);

Cand Observabil este gata, puteți folosi subscribeOn și observeOn pentru a specifica firele pe care ar trebui să le utilizeze și pentru a le abona.

java fetchFromGoogle .subscribeOn (Schedulers.newThread ()) // Creați un nou subiect .observeOn (AndroidSchedulers.mainThread ()) // Utilizați subiectul .Uubscribe (noua acțiune1() @Oversă apel public void (String s) view.setText (view.getText () + "\ n" + s); // Schimbați o vizualizare);

S-ar putea să vă mai gândiți că abordarea reactivă nu este drastic mai bună decât utilizarea AsyncTask sau manipulant clase. Ai dreptate, nu ai nevoie de ReactiveX dacă trebuie să gestionezi doar o lucrare de fundal.

Acum, ia în considerare un scenariu care ar avea ca rezultat o bază de cod complexă dacă ați folosit abordarea convențională. Să presupunem că trebuie să preluați în paralel date din două (sau mai multe) site-uri și să actualizați a Vedere numai când toate cererile au fost finalizate. Dacă urmați abordarea convențională, va trebui să scrieți o mulțime de cod inutil pentru a vă asigura că cererile au fost efectuate fără erori.

Luați în considerare un alt scenariu în care trebuie să începeți un job de fundal numai după ce un alt loc de muncă de fundal sa încheiat. Folosind abordarea convențională, acest lucru ar duce la apelări imbricate.

Cu operatorii ReactiveX, ambele scenarii pot fi manipulate cu un cod foarte mic. De exemplu, dacă trebuie să utilizați fetchData pentru a prelua conținutul a două site-uri web, de exemplu Google și Yahoo, ați crea două Observabil obiecte și utilizați subscribeOn pentru a le face să ruleze pe fire diferite.

java fetchFromGoogle = fetchFromGoogle.subscribeOn (Schedulers.newThread ()); fetchFromYahoo = fetchFromYahoo.subscribeOn (Schedulers.newThread ());

Pentru a rezolva primul scenariu în care ambele cereri trebuie executate în paralel, puteți utiliza funcția zip operator și să vă abonați la Observabil se întoarce.

java / / Fetch din ambele simultan Observabile zipped = Observation.zip (fetchFromGoogle, fetchFromYahoo, noul Func2() @Override apel public String (String google, String yahoo) // Face ceva cu rezultatele celor două fire returnează google + "\ n" + yahoo; );

În mod similar, pentru a face față celui de-al doilea scenariu, puteți utiliza funcția concat operator pentru a rula firele una după alta.

java observabil concatenated = Observable.concat (fetchFromGoogle, fetchFromYahoo); // Emiteți rezultatele unul după altul

5. Manipularea evenimentelor

RxAndroid are o clasă numită ViewObservable care facilitează gestionarea evenimentelor asociate Vedere obiecte. Următorul fragment de cod vă arată cum să creați un ViewObservable care poate fi folosit pentru a face față evenimentelor de tip clic Buton.

"butonul java Button myButton = (Button) findViewById (R.id.my_button); / / Crearea unui buton dintr-un aspect

Observabil clicksObservable = ViewObservable.clicks (myButton); // Crearea unei vizualizăriObservabile pentru butonul "

Acum vă puteți abona clicksObservable și utilizați oricare dintre operatorii pe care i-ați învățat în secțiunile anterioare. De exemplu, dacă doriți ca aplicația să ignore primele patru clicuri ale butonului și să înceapă să răspundă de la al cincilea clic, puteți utiliza următoarea implementare:

java clicksObservable .skip (4) // Sari peste primele 4 clicuri .subscribe (noua Action1() @Override apel public void (OnClickEvent onClickEvent) Log.d ("Faceți clic pe Acțiune", "Apăsat!"); // Tipărit din cel de-al cincilea clic în plus);

Concluzie

În acest tutorial, ați învățat cum să utilizați observatorii, observatorii și operatorii ReactiveX pentru a gestiona mai multe operații și evenimente asincrone. Deoarece lucrul cu ReactiveX presupune programare funcțională, reactivă, o paradigmă de programare pe care majoritatea dezvoltatorilor de Android nu o folosesc, nu fi prea tare pe seama ta dacă nu o faci drept prima dată. De asemenea, trebuie să știți că codul ReactiveX va fi mult mai ușor de citit dacă utilizați un limbaj de programare modern, cum ar fi Kotlin, care susține funcții de ordin superior.

Pentru a afla mai multe despre extensiile reactive, vă încurajez să răsfoiți resursele disponibile la ReactiveX.

Cod