Utvikling av en kompleks Android-app som har mange nettverkstilkoblinger, brukerinteraksjoner og animasjoner betyr ofte å skrive kode som er full av nestede tilbakeringinger. Slike koden, noen ganger kalt callback helvete, er ikke bare lang og vanskelig å forstå, men også feilaktig. ReactiveX tilbyr en alternativ tilnærming som er både klar og konsis, for å administrere asynkrone oppgaver og hendelser.
RxJava er en JVM-implementering av ReactiveX, utviklet av NetFlix, og er veldig populær blant Java-utviklere. I denne opplæringen lærer du hvordan du bruker RxJava-bindinger for Android, eller RxAndroid for kort, i Android-prosjektene dine.
For å bruke RxAndroid i et Android Studio-prosjekt, legg det til som en kompilere
avhengighet i appmodulets build.gradle.
java kompilere 'io.reactivex: rxandroid: 0.25.0'
Når du arbeider med ReactiveX, bruker du observerbare observatører og observatører. Du kan tenke på en observerbar som et objekt som sender data og en observatør som et objekt som bruker dataene. I RxJava og RxAndroid er observatører forekomster av Observer
grensesnitt, og observerbare er forekomster av observer
klasse.
De observer
klassen har mange statiske metoder, kalt operatører, å lage observer
objekter. Følgende kode viser hvordan du bruker bare
operatør for å lage en veldig enkel observer
som utsender en enkelt string
.
java Observerbar
Den observerbare vi nettopp har opprettet, vil kun gi ut data når den har minst en observatør. For å opprette en observatør, oppretter du en klasse som implementerer Observer
grensesnitt. De Observer
grensesnittet har intuitivt navngitte metoder for å håndtere ulike typer meldinger det kan motta fra det observerbare. Her er en observatør som kan skrive ut string
utsendt av det observerbare vi opprettet tidligere:
"Java Observer
@Override public void onError (Throwable e) // Kalt når det observerbare møter en feil @Override public void onNext (String s) // Kalt hver gang det observerbare sender data Log.d ("MY OBSERVER", s) ; ; "
For å tilordne en observatør til en observerbar, bør du bruke abonnere
metode, som returnerer a Abonnement
gjenstand. Følgende kode gjør myObserver
observere myObservable
:
java abonnement mySubscription = myObservable.subscribe (myObserver);
Så snart en observatør legges til det observerbare, utsender det sine data. Derfor, hvis du kjører koden nå, vil du se Hallo skrevet ut i Android Studio logcat vindu.
Du har kanskje lagt merke til at vi ikke brukte onCompleted
og onError
metoder i myObserver
. Da disse metodene ofte blir ubrukt, har du også muligheten til å bruke handling1
grensesnitt, som inneholder en enkelt metode som heter anrop
.
java Action1
Når du passerer en forekomst av handling1
til abonnere
metode, den anrop
Metoden er påkalt når det observerbare sender data.
java abonnement mySubscription = myObservable.subscribe (myAction1);
For å frigjøre en observatør fra det observerbare mens det observerbare fortsatt utsender data, kan du ringe Avslutte abonnementet
metode på Abonnement
gjenstand.
java mySubscription.unsubscribe ();
Nå som du vet hvordan du lager observatører og observables, la meg vise deg hvordan du bruker ReactiveXs operatører som kan opprette, transformere og utføre andre operasjoner på observerbare data. La oss begynne med å skape en litt mer avansert observer
, en som sender ut elementer fra en rekke Integer
objekter. For å gjøre det må du bruke fra
operatør, som kan generere en observer
fra arrays og lister.
"java observerbar
myArrayObservable.subscribe (ny Action1
Når du kjører denne koden, vil du se hvert av tallene i arrayet som skrives ut en etter en.
Hvis du er kjent med JavaScript, Ruby eller Kotlin, kan du være kjent med høyere rekkefølge funksjoner som kart
og filter
, som kan brukes når du arbeider med arrays. ReactiveX har operatører som kan utføre lignende operasjoner på observerbare data. Men fordi Java 7 ikke har lambdas og høyereordningsfunksjoner, må vi gjøre det med klasser som simulerer lambdas. For å simulere en lambda som tar ett argument, må du lage en klasse som implementerer func1
grensesnitt.
Slik kan du bruke kart
operatør for å firkantet hvert element av myArrayObservable
:
java myArrayObservable = myArrayObservable.map (ny Func1
Legg merke til at anropet til kart
operatør returnerer en ny observer
, det endrer ikke originalen observer
. Hvis du abonnerer på myArrayObservable
nå vil du motta firkanter av tallene.
Operatører kan kjedes. For eksempel bruker den følgende kodeblokken hoppe
operatør for å hoppe over de to første tallene, og deretter filter
operatør for å ignorere odde tall:
"java myArrayObservable .skip (2) // Hopp de to første elementene .filter (nytt Func1
// Utsender 4 og 6 "
Observatørene og observablene vi opprettet i de foregående delene, jobbet på en enkelt tråd, Android's UI-tråd. I denne delen vil jeg vise deg hvordan du bruker ReactiveX til å administrere flere tråder og hvordan ReactiveX løser problemet med tilbakekallingshelvete.
Anta at du har en metode som heter fetchData
som kan brukes til å hente data fra en API. La oss si at det aksepterer en nettadresse som parameter og returnerer innholdet i svaret som en string
. Følgende kodestykke viser hvordan det kan brukes.
java String content = fetchData ("http://www.google.com"); // henter innholdet på google.com som en streng
Denne metoden må kjøre på egen tråd, fordi Android tillater ikke nettverksoperasjoner på brukergrensesnittet. Dette betyr at du enten vil opprette en AsyncTask
eller opprett en Tråd
som bruker a handler
.
Med ReactiveX har du imidlertid et tredje alternativ som er litt mer konsistent. Bruker subscribeOn
og observeOn
operatører, kan du spesifikt spesifisere hvilken tråd som skal kjøre bakgrunnsjobben, og hvilken tråd som skal håndtere brukergrensesnittoppdateringene.
Følgende kode oppretter en egendefinert observer
bruker skape
operatør. Når du oppretter en observer
På denne måten må du implementere Observable.OnSubscribe
grensesnitt og kontrollere hva det sender ut ved å ringe onNext
, onError
, og onCompleted
metoder selv.
java Observerbar
Når observer
er klar, kan du bruke subscribeOn
og observeOn
å spesifisere tråder den skal bruke og abonnere på den.
java fetchFromGoogle .subscribeOn (Schedulers.newThread ()) // Opprett en ny tråd .observeOn (AndroidSchedulers.mainThread ()) // Bruk brukergrensesnittet .subscribe (new Action1
Du kan fortsatt tenke at den reaktive tilnærmingen ikke er drastisk bedre enn å bruke AsyncTask
eller handler
klasser. Du har rett, du trenger ikke virkelig ReactiveX hvis du bare må klare en bakgrunnsjobb.
Nå vurderer et scenario som ville resultere i en kompleks kodebase hvis du brukte den konvensjonelle tilnærmingen. La oss si at du må hente data fra to (eller flere) nettsteder parallelt og oppdatere a Utsikt
bare når alle forespørsler har fullført. Hvis du følger den konvensjonelle tilnærmingen, må du skrive mye unødvendig kode for å sikre at forespørslene er fullført uten feil.
Vurder et annet scenario der du må starte en bakgrunnsjobb bare etter at en annen bakgrunnsjobb har fullført. Ved hjelp av konvensjonell tilnærming vil dette resultere i nestede tilbakeringinger.
Med ReactiveXs operatører kan begge scenariene håndteres med svært liten kode. For eksempel, hvis du må bruke fetchData
for å hente innholdet på to nettsteder, for eksempel Google og Yahoo, ville du opprette to observer
objekter, og bruk subscribeOn
metode for å få dem til å løpe på forskjellige tråder.
java fetchFromGoogle = fetchFromGoogle.subscribeOn (Schedulers.newThread ()); fetchFromYahoo = fetchFromYahoo.subscribeOn (Schedulers.newThread ());
For å håndtere det første scenariet der begge forespørslene må kjøre parallelt, kan du bruke glidelås
operatør og abonnere på observer
det kommer tilbake.
java // Hent fra begge samtidig Observable
På samme måte, for å håndtere det andre scenariet, kan du bruke concat
operatør for å kjøre trådene etter hverandre.
java Observerbar
RxAndroid har en klasse som heter ViewObservable
som gjør det enkelt å håndtere hendelser knyttet til Utsikt
objekter. Følgende kodestykke viser deg hvordan du lager en ViewObservable
som kan brukes til å håndtere klikkhendelser av a Knapp
.
"java Button myButton = (Button) findViewById (R.id.my_button); // Lag en knapp fra et layout
observer
Du kan nå abonnere på clicksObservable
og bruk noen av operatørene du lærte om i de forrige avsnittene. Hvis du for eksempel vil at appen din skal hoppe over de fire første klikkene på knappen og begynne å svare fra femte klikk, kan du bruke følgende implementering:
java klikk. Observerbar .skip (4) // Hopp over de første 4 klikkene. Abonnere (ny Action1
I denne opplæringen lærte du hvordan du bruker ReactiveXs observatører, observables og operatører til å håndtere flere asynkrone operasjoner og hendelser. Som å jobbe med ReactiveX involverer funksjonell, reaktiv programmering, er et programmeringsparadigm de fleste Android-utviklere ikke vant til, ikke vær for vanskelig på deg selv hvis du ikke klarer det riktig første gang. Du bør også vite at ReactiveX-koden vil være mye mer lesbar hvis du bruker et moderne programmeringsspråk, for eksempel Kotlin, som støtter høyere rekkefølgefunksjoner.
Hvis du vil vite mer om reaktive utvidelser, oppfordrer jeg deg til å bla gjennom ressursene som er tilgjengelige på ReactiveX.