Als je een Android-ontwikkelaar bent, heb je misschien goede dingen gehoord over RxJava, een populaire opensource-implementatie van de ReactiveX-bibliotheek die reactief programmeren met de Java Virtual Machine (JVM) mogelijk maakt.
RxJava is ontworpen om de pijn weg te nemen bij het werken met asynchrone gegevensstromen - hoewel zoals je zult zien, RxJava's definitie van "gegevens" behoorlijk breed is. Omdat RxJava een JVM-compatibele bibliotheek is, kun je het op een groot aantal platforms gebruiken, maar in deze serie laat ik je zien hoe je RxJava 2 voor Android-ontwikkeling gebruikt.
Aan het einde van deze serie heb je alle essentiële RxJava 2 onder de knie, zodat je kunt beginnen met het maken van zeer reactieve apps die een breed scala aan synchrone en asynchrone gegevens kunnen verwerken - allemaal met behulp van code die beknopter en hanteerbaarder is dan je normaal zou zijn kunnen bereiken met alleen Java.
Naast een introductie voor RxJava nieuwkomers, als je een RxJava 1-veteraan bent die op zoek is naar de sprong naar RxJava 2, zal deze serie helpen deze overgang zo soepel mogelijk te laten verlopen. Hoewel upgraden naar de nieuwste versie van een bibliotheek misschien niet zo belangrijk is, is RxJava 2 niet uw gebruikelijke update, het is een complete herschrijving van RxJava. Met zoveel veranderingen is het gemakkelijk om in de war te raken, dus enige tijd nemen om vertrouwd te raken met RxJava 2 vanuit het perspectief van een beginner kan u op de lange termijn veel tijd en frustratie besparen.
In dit eerste bericht behandel ik wat RxJava is en de belangrijkste voordelen die het Android-ontwikkelaars biedt. We zullen ook een diepgaande blik werpen op de kerncomponenten van ieder RxJava-project: waarnemers
, observabelen
, en abonnementen. Aan het einde van deze zelfstudie hebt u een eenvoudige toepassing "Hello World" gemaakt, die al deze kerncomponenten bevat.
De andere grote bouwstenen van RxJava zijn operatoren, dus in deel twee zal ik de verschillende manieren onderzoeken waarop je operatoren kunt gebruiken om de gegevens van je applicatie te transformeren, combineren, filteren en manipuleren.
In het laatste deel gaan we verder dan de centrale RxJava-bibliotheek en bekijken we RxAndroid, een hele bibliotheek die vol zit met alle Android-specifieke extensies die je nodig hebt om het volledige potentieel van reactief programmeren voor Android te ontgrendelen.
We hebben veel te bieden, dus laten we beginnen met de essentie:
RxJava is een bibliotheek waarmee u toepassingen kunt maken in de reactieve programmeerstijl. In de kern biedt reactieve programmering een schone, efficiënte manier om te verwerken en te reageren op stromen van real-time gegevens, inclusief gegevens met dynamische waarden.
Deze datastromen hoeven niet noodzakelijkerwijs hebben om de vorm aan te nemen van traditionele gegevenstypen, aangezien RxJava vrijwel alles behandelt als een stroom gegevens - alles van variabelen tot eigenschappen, caches en zelfs gebruikersinvoergebeurtenissen zoals klikken en swipes.
De gegevens die door elke stream worden uitgezonden, kunnen een waarde, een fout of een "voltooid" signaal zijn, hoewel u niet noodzakelijk de laatste twee hoeft te implementeren. Nadat u uw gegevens-uitstralende streams hebt gemaakt, combineert u ze met reactieve objecten die deze gegevens gebruiken en vervolgens in actie komen, waarbij verschillende acties worden uitgevoerd afhankelijk van wat de stream heeft uitgezonden. RxJava bevat een hele reeks nuttige operatoren om met streams te werken, waardoor het eenvoudig is om dingen te doen zoals filteren, in kaart brengen, vertragen, tellen en nog veel meer.
Om deze workflow van gegevensstromen en objecten die erop reageren te creëren, breidt RxJava het ontwerppatroon van de Observer uit. In wezen heb je dat in RxJava waarneembaar
objecten die een gegevensstroom uitzenden en vervolgens beëindigen, en Waarnemer
objecten die zich abonneren op waarneembaar
s. Een Waarnemer
ontvangt een melding telkens wanneer deze zijn toegewezen waarneembaar
geeft een waarde, een fout of een voltooid signaal af.
Dus op een zeer hoog niveau, RxJava is alles over:
waarneembaar
.waarneembaar
sommige gegevens die moeten worden uitgezonden.Waarnemer
.Waarnemer
aan een waarneembaar
.Waarnemer
taken uitvoeren wanneer deze een emissie ontvangt van de toegewezen emissie waarneembaar
.Het leren van nieuwe technologie vereist tijd en moeite, en als een data-georiënteerde bibliotheek is RxJava niet altijd de gemakkelijkste API om grip te krijgen op.
Om u te helpen beslissen of het leren van RxJava de initiële investering waard is, laten we enkele van de belangrijkste voordelen van het toevoegen van de RxJava-bibliotheek aan uw Android-projecten verkennen.
Code die complex, uitgebreid en moeilijk te lezen is, is altijd slecht nieuws. Rommelige code is meer vatbaar voor fouten en andere inefficiënties, en als er fouten optreden, zult u een veel moeilijkere tijd hebben om de bron van deze fouten op te sporen als uw code een puinhoop is.
Zelfs als je project zonder fouten is opgebouwd, kan complexe code je nog steeds achtervolgen - meestal wanneer je besluit een paar maanden later een update van je app uit te brengen, je project op te starten en direct geconfronteerd wordt met een muur van verwarde, verwarrende code!
RxJava vereenvoudigt de code die nodig is om gegevens en gebeurtenissen af te handelen door u toe te staan te beschrijven wat u wilt bereiken, in plaats van een lijst met instructies te schrijven die uw app moet doorlopen. RxJava biedt ook een standaardworkflow die u kunt gebruiken om alle gegevens en gebeurtenissen in uw toepassing te verwerken - maak een waarneembaar
, Creëer een Waarnemer
, wijs het waarneembare aan die waarnemer toe, spoel af en herhaal. Deze formulebenadering zorgt voor zeer duidelijke, voor de mens leesbare code.
Moderne Android-applicaties moeten kunnen multi-tasken. Op zijn minst verwachten uw gebruikers dat ze kunnen blijven communiceren met de gebruikersinterface van uw app terwijl uw toepassing op de achtergrond wat werk verricht, zoals het beheren van een netwerkverbinding, het downloaden van een bestand of het afspelen van muziek. Het probleem is dat Android standaard een thread heeft, dus als je app ooit multi-taskt, moet je wat extra threads maken.
Out of the box biedt Android een aantal manieren om extra threads te maken, zoals services en IntentServices
, maar geen van deze oplossingen is bijzonder gemakkelijk te implementeren en ze kunnen snel resulteren in complexe, uitgebreide code die gevoelig is voor fouten.
RxJava streeft ernaar de pijn weg te nemen bij het maken van multi-threaded Android-apps, door middel van speciale planners en operatoren. Deze bieden u een eenvoudige manier om de thread te specificeren waar het werk moet worden uitgevoerd en de thread waar de resultaten van dit werk moeten worden geplaatst. RxJava 2.0 bevat standaard een aantal planners, waaronder Schedulers.newThread
, welke is vooral nuttig omdat het een nieuwe thread creëert.
Als u de thread wilt wijzigen waar werk wordt uitgevoerd, hoeft u alleen te wijzigen waar een waarnemer een waarneembaar abonnement onderschrijft, met behulp van de subscribeOn
operator. Hier maken we bijvoorbeeld een nieuwe thread en geven we aan dat het werk moet worden uitgevoerd op deze nieuwe thread:
observable.subscribeOn (Schedulers.newThread ())
Een ander al lang bestaand probleem met multithreading op Android is dat u de gebruikersinterface van uw app alleen kunt bijwerken vanuit de hoofdthread. Wanneer u de resultaten van wat achtergrondwerk naar de gebruikersinterface van uw app wilt publiceren, moet u meestal een speciaal hiervoor aangemaakt handler
.
Nogmaals, RxJava heeft een veel rechtlijniger oplossing. U kunt de observeOn
operator om te specificeren dat een waarneembare zijn meldingen moet verzenden met een andere planner, waardoor u in essentie de gegevens van uw Observable naar de thread van uw keuze kunt sturen, inclusief de UI-thread.
Dit betekent dat je met slechts twee regels code een nieuwe thread kunt maken en de resultaten van het uitgevoerde werk op deze thread naar de belangrijkste UI-thread van Android kunt verzenden:
.subscribeOn (Schedulers.newThread ()) .observeOn (AndroidSchedulers.mainThread ())
Oke dus technisch gezien we vals spelen hier een beetje AndroidSchedulers.mainThread
is alleen beschikbaar als onderdeel van de RxAndroid-bibliotheek, waar we pas in deel drie naar zullen kijken. Dit voorbeeld geeft je echter een glimp van de kracht van RxJava en RxAndroid om een deel van de Android-ontwikkeling te vereenvoudigen dat bekend staat als overdreven ingewikkeld te zijn.
Observables zenden hun gegevens uit op een manier die de manier waarop gegevens zijn gemaakt volledig verbergt. Omdat uw waarnemers niet eens kunnen zien hoe de gegevens zijn gemaakt, bent u vrij om uw gegevens te implementeren waarneembaar
s op elke gewenste manier.
Zodra u uw hebt geïmplementeerd waarneembaar
s, RxJava biedt een enorm aantal operatoren die u kunt gebruiken om de gegevens die door deze worden verzonden te filteren, samen te voegen en te transformeren waarneembaar
s. Je kunt zelfs meer en meer operators samenvoegen tot je hebt gemaakt precies de datastream die uw applicatie nodig heeft.
U kunt bijvoorbeeld gegevens uit meerdere streams combineren, de nieuw samengevoegde stream filteren en de resulterende gegevens vervolgens gebruiken als invoer voor een volgende gegevensstroom. En onthoud dat in RxJava vrijwel alles wordt behandeld als een gegevensstroom, dus je kunt deze operatoren zelfs toepassen op niet-traditionele "gegevens", zoals klikgebeurtenissen.
Voorbij zijn de dagen waarop een app weg zou kunnen komen met het laden van een pagina met inhoud en dan te wachten tot de gebruiker op de volgende knop. Tegenwoordig moet uw typische mobiele app kunnen reageren op een steeds groeiende verscheidenheid aan gebeurtenissen en gegevens, idealiter in realtime. Uw standaard app voor sociaal netwerken moet bijvoorbeeld constant luisteren naar binnenkomende likes, opmerkingen en vriendschapsverzoeken, terwijl een netwerkverbinding op de achtergrond wordt beheerd en onmiddellijk reageert wanneer de gebruiker op het scherm tikt of het scherm veegt.
De RxJava-bibliotheek is ontworpen om een breed scala aan gegevens en gebeurtenissen tegelijkertijd en in realtime te kunnen beheren, waardoor het een krachtige tool is voor het creëren van het soort zeer responsieve applicaties dat moderne mobiele gebruikers verwachten.
Als je hebt besloten dat RxJava je Android-ontwikkelingspraktijk wel iets te bieden heeft, is de eerste stap om een RxJava-master te worden, het toevoegen van de bibliotheek aan je project.
Maak een nieuw Android Studio-project met de instellingen van uw keuze en open vervolgens uw moduleniveau build.gradle bestand en voeg de nieuwste versie van io.reactivex.rxjava2: rxjava
als een afhankelijkheid.
Op het moment van schrijven was RxJava 2.0.5 de meest recente uitgave, dus mijn build.gradle bestand ziet er als volgt uit:
afhankelijkheden compile fileTree (dir: 'libs', include: ['* .jar']) androidTestCompile ('com.android.support.test.espresso: espresso-core: 2.2.2', exclude group: 'com. android.support ', module:' support-annotaties ') compileer' com.android.support:appcompat-v7:25.1.0 'testCompile' junit: junit: 4.12 'compile' io.reactivex.rxjava2: rxjava: 2.0. 5 '
Klik hier als u daarom wordt gevraagd Synchroniseer nu.
Open vervolgens je Hoofdactiviteit
bestand en voeg de import toe die je nodig hebt om te werken met de kernfuncties van RxJava:
import io.reactivex.Observable; importeer io.reactivex.ObservableEmitter; importeer io.reactivex.ObservableOnSubscribe; importeer io.reactivex.Observer; importeer io.reactivex.disposables.Disposable;
Als u migreert van RxJava 1, is deze invoer mogelijk niet wat u verwachtte, omdat RxJava 1 een geheel andere pakketnaam gebruikte (rx
precies zijn).
Dit is echter geen willekeurige naamswijziging: de verschillende pakketnamen geven u de mogelijkheid RxJava 1 en RxJava 2 naast elkaar in hetzelfde project te gebruiken. Als je halverwege een project bent dat RxJava 1 gebruikt, kun je de RxJava 2-bibliotheek toevoegen en onmiddellijk de bijgewerkte 2 functies gebruiken zonder je RxJava 1-code te breken.
Als u uw RxJava-reis begint met versie 2, moet u er rekening mee houden dat als u RxJava-zelfstudies tegenkomt of als u code gebruikt met de rx
pakketnaam, dan is dit de RxJava 1-code en het is onwaarschijnlijk dat deze compatibel is met de versie 2-bibliotheek.
Tot nu toe hebben we alleen RxJava op een zeer hoog niveau bekeken. Het is tijd om specifieker te worden en een diepgaande blik te werpen op twee van de belangrijkste componenten die keer op keer opduiken tijdens uw RxJava-werk: Waarnemer
s en waarneembaar
s.
Aan het einde van dit gedeelte heeft u niet alleen een goed begrip van deze twee kerncomponenten, maar heeft u ook een volledig functionerende applicatie gemaakt die bestaat uit een waarneembaar
die gegevens uitzendt en een Waarnemer
die reageert op deze emissies.
waarneembaar
Een waarneembaar
is vergelijkbaar met een Iterable
daarin, gegeven een reeks, zal het door die reeks herhalen en elk item uitzenden, hoewel waarneembaar
s beginnen meestal pas met het uitzenden van gegevens tot een Waarnemer
abonneert op hen.
Elke keer een waarneembaar
stoot een item uit, het meldt zijn toegewezen Waarnemer
de ... gebruiken onNext ()
methode. Eens een waarneembaar
heeft al zijn waarden doorgegeven, het wordt beëindigd door een van beide te bellen:
onComplete
: Geroepen als de operatie een succes was. OnError
: Geroepen als een Uitzondering
is gegooid.Laten we een voorbeeld bekijken. Hier maken we een waarneembaar dat de cijfers uitzendt 1, 2, 3 en 4, en eindigt dan.
waarneembaarobserveable = Observable.create (nieuw ObservableOnSubscribe () @Override public void subscribe (ObservableEmitter e) gooit Uitzondering // Use onNext om elk item in de stream uit te zenden // e.onNext (1); e.onNext (2); e.onNext (3); e.onNext (4); // Als Observable alle items in de reeks heeft verzonden, roept u onComplete // e.onComplete () aan; );
Merk op dat ik in dit voorbeeld precies beschrijf wat er gebeurt, dus laat de hoeveelheid code je niet afschrikken! Dit is veel meer code dan u gewoonlijk gebruikt om te maken waarneembaar
s in uw real-life RxJava-projecten.
Waarnemer
s zijn objecten die u toewijst aan een waarneembaar
, de ... gebruiken abonneren ()
operator. Eens een Waarnemer
is geabonneerd op een waarneembaar
, het zal reageren wanneer het is Waarnemer
geeft een van de volgende:
onNext
: De waarneembaar
heeft een waarde uitgezonden.OnError
: Er is een fout opgetreden.onComplete
: De waarneembaar
is klaar met het uitzenden van alle waarden.Laten we een maken Waarnemer
dat is geabonneerd op onze 1, 2, 3, 4 waarneembaar
. Om dingen simpel te houden, dit Waarnemer
zal reageren op onNext
, OnError
en onComplete
door een bericht af te drukken naar Android Studio's Logcat Monitor:
Waarnemerwaarnemer = nieuwe waarnemer () @Override public void onSubscribe (Disposable d) Log.e (TAG, "onSubscribe:"); @Override public void onNext (Integer value) Log.e (TAG, "onNext:" + value); @Override public void onError (Throwable e) Log.e (TAG, "onError:"); @Override public void onComplete () Log.e (TAG, "onComplete: All Done!"); ; // Maak ons abonnement // observeable.subscribe (waarnemer);
Open de Logcat-monitor van Android Studio door de. Te selecteren Android-monitor Klik op de tab onder aan het venster van Android Studio (waar de cursor zich in de onderstaande schermafbeelding bevindt) en selecteer de logcat tab.
Om deze code op de proef te stellen, koppelt u uw fysieke Android-apparaat aan uw ontwikkelmachine of voert u uw project uit op een compatibele AVD. Zodra je app op het scherm verschijnt, zou je de gegevens moeten zien die worden uitgestraald door je Observable.
Hoewel ons project met succes gegevens verzendt, is de code die we gebruiken niet precies beknopt, met name de code die we gebruiken om onze code te maken waarneembaar
.
Gelukkig biedt RxJava een aantal gemaksmethoden waarmee je een waarneembaar
gebruik van veel minder code:
U kunt de .net()
operator om elk object in een te converteren waarneembaar
. Het resultaat waarneembaar
zal dan het originele object uitzenden en aanvullen.
Hier maken we bijvoorbeeld een waarneembaar
dat zal een enkele string uitzenden naar al zijn waarnemers
:
waarneembaarobserveable = Observable.just ("Hello World!");
Observable.from ()
De .van()
operator stelt u in staat een verzameling objecten om te zetten in een waarneembare stream. Je kunt een array omzetten in een waarneembaar
gebruik makend van Observable.fromArray
, een Callable
in een waarneembaar
gebruik makend van Observable.fromCallable
, en een Iterable
in een waarneembaar
gebruik makend van Observable.fromIterable
.
Observable.range ()
U kunt de .range ()
operator om een reeks opeenvolgende gehele getallen uit te zenden. Het eerste gehele getal dat u opgeeft, is de beginwaarde en het tweede is het aantal gehele getallen dat u wilt uitzenden. Bijvoorbeeld:
waarneembaarwaarneembaar = Waarneembaar.bereik (0, 5);
Observable.interval ()
Deze operator maakt een waarneembaar
die een oneindige reeks van oplopende getallen uitstuurt, waarbij elke emissie wordt gescheiden door een tijdsinterval dat door jou is gekozen. Bijvoorbeeld:
waarneembaarobserveable = Observable.interval (1, TimeUnit.SECONDS)
Observable.empty ()
De leeg()
operator maakt een waarneembaar
die geen items uitzendt, maar normaal wordt beëindigd, wat handig kan zijn als u snel een wilt maken waarneembaar
voor testdoeleinden.
waarneembaarobserveable = Observable.empty ();
In dit artikel hebben we de fundamentele bouwstenen van RxJava besproken.
Op dit moment weet u hoe u kunt creëren en waarmee u werkt waarnemers
en observabelen
, en hoe u een abonnement kunt maken zodat uw observabelen
kan beginnen met het uitzenden van gegevens. We hebben ook kort gekeken naar een aantal operatoren waarmee je een reeks verschillende kunt creëren observabelen
, met veel minder code.
Operators zijn echter niet alleen een handige manier om de hoeveelheid code die u nodig hebt om te schrijven te verminderen! Een maken Waarnemer
en een waarneembaar
is eenvoudig genoeg, maar operators zijn waar je echt begint te zien wat mogelijk is met RxJava.
Dus in het volgende bericht zullen we enkele van de krachtigste operators van RxJava verkennen, inclusief operators die eindelijk multi-threading op Android een pijnvrije ervaring kunnen maken. Blijf op de hoogte om de echte kracht van de RxJava-bibliotheek te leren kennen.
Bekijk in de tussentijd een aantal van onze andere berichten en cursussen over Android-ontwikkeling hier op Envato Tuts+!
Waarneembare dataflow-diagrammen zijn afkomstig van de ReactiveX-documentatie en zijn gelicentieerd onder Creative Commons Attribution 3.0-licentie.