Kuinka tehdä Androidista enemmän Rx - 5 vinkkiä ja vinkkejä

Jos käytät RxJavaa päivittäisessä rutiinissasi, tulet todennäköisesti jonain päivänä kohtaan, johon haluat ... laita RxJava kaikkialle! Annan antaa sinulle viisi käytännön neuvoja.

RxJavan käyttäminen kaikkialla ei ole huono idea (yleensä). On normaalia, että ajattelet "Hei, se näyttää paljon tyylikämmältä, jos voisin vain laittaa tämän RxJava-virtaan sen sijaan, että käyttäisin silmukkaa / Käsittelijä / Async-tehtävää / jotain muuta rumaa ratkaisua". Kyllä, se on siistiä. Jos vain voisin…

No, minulla on hyviä uutisia sinulle - RxJavan avulla voit tehdä suurimman osan asioista, joista olet unelmoinut! Annan teille viisi neuvoa asioista, joista pidän ja joita usein käytän projekteissani.

Nämä koodinpätkät toimivat sekä RxJavassa että RxJava2: ssa. Tässä artikkelissa oletetaan, että sinulla on perustietoja RxJavasta. Jos ei, suosittelen, että luet ensin joitain muita artikkeleita (tämä RxJavalla - tuotantolinjalla - tarjoaa loistavan alun).

# 1 Kaksoisnapsautuksen tunnistus

Sinulla on joitain painikkeita sovelluksessasi ja haluat selvittää, napsautettiinko näitä painikkeita kahdesti. Helppo, eikö niin? Kyllä, kaikki mitä tarvitset tämän tekemiseen, on tehdä laskuri, tarkistaa jokainen napsautus, siirtää laskuria askeleen verran ja muistaa nollata laskuri jälkikäteen. Ei millään tavalla, tähän on oltava puhtaampaa tapaa. Tietysti tässä se on:

yksityinen PublishSubject  eventSubject = PublishSubject.create ();
julkinen staattinen lopullinen int TIME_BETWEEN_EVENTS_MILLIS = 500;
julkinen staattinen lopullinen int NUMBER_OF_EVENTS = 2;
julkinen DoubleClick () {
    eventSubject
        .buffer (eventSubject.debounce (TIME_BETWEEN_EVENTS_MILLIS,
            TimeUnit.MILLISECONDS))
        .suodatin (tapahtumat -> tapahtumat.koko () == NUMBER_OF_EVENTS)
        .tilaus (tapahtumat -> doSomething ());
    button.setOnClickListener ((painike) ->
        eventSubject.onNext (tosi));
}

PublishSubject-sovelluksella voimme lähettää omia tuotteitamme ja tarttua niihin. Kiinnityksen jälkeen tarkistamme, onko tapahtumien lukumäärä sama kuin haluamamme arvo. Voit tietysti tehdä sen jokaisella tapahtumalla - saada tekstiä TextView-ohjelmasta, saada napsautuksia muusta näkymästä tai muusta.

# 2 API-pyyntöjen toistaminen 10 minuutin välein

Operaattorin repeWhen käyttö voi viivästystuloksiin yhdistettynä johtaa tilauksen viivästymiseen jonkin ajan kuluttua. Jos haluat jostain syystä pyytää uusia tietoja sovellusliittymältä 10 minuutin välein, voit tehdä sen RxJavan kanssa yhdellä rivillä:

sourceObservable.repeatWhen (valmis -> suoritettu.viive (10,
    TimeUnit.MINUTES));

Muista vain, että havainnoitava toistuu vain, jos edellinen valmistui.

# 3 Kahden riippuvaisen objektin yhdistäminen

Oletetaan, että saamme kissoja API: lta, ja haluamme jokaisesta kissasta saada leluja (jotka ovat kissasta riippuvaisia). Tämän jälkeen haluamme saada objektin yhdistettynä CatAndToys -sovelluksiin - tämä on mahdollista tehdä RxJavan kanssa käyttämällä flatMapin toista parametria (jota ei niin usein käytetä), jota

[…] Yhdistää lähteistä havaittavissa olevat kohteet niiden lähteiden laukaisemiin havainnoitaviin, emittoiden nämä yhdistelmät.

Lähde: RxJavan dokumentaatio

Anna koodin puhua puolestaan:

Havaittavissa oleva  catWithToysObservable =
    getCatObservable ()
        .flatMap ((kissa) -> getToysForCatObservable (kissa),
            (kissa, lelut) -> uudet CatWithToys (kissa, lelut));

Näemme tämän ensimmäisen parametrin flatMapissa. Cat ottaa parametriksi ja palauttaa Lelut. Sitten toinen parametri vie kissan ja lelut (ensimmäisen toiminnon tulos) ja palauttaa CatWithToys-objektin. Tällä tavalla voit yhdistää monia riippuvaisia ​​pyyntöjä sovellusliittymään käyttämättä sisäkkäisiä flatMap-operaattoreita.

# 4 Pyydä sivutusta

Jos haluat sivua jonkin objektin kautta API: sta, voit tehdä sen helposti RxJavan avulla. Temppu on yhdistää kaikki sivut, kunnes saavutat jonkin lopullisen pisteen (esim. Viimeinen pyyntö antaa sinulle tyhjiä tuloksia tai muuten kappaleiden lukumäärä on oikea ja oikea). Katsotaanpa koodia:

julkinen havaittavissa oleva > getAllUsers () {
    palauta getUsersObservable (nolla);
}
yksityinen havaittavissa oleva > getUsersObservable (lopullinen merkkijono
    lastUserId) {
    palauta apiAdapter
        .getData (lastUserId)
        .filter (userList ->! isLastPage (userList))
        .flatMap (tämä :: getNextPageUsersObservable);
}
yksityinen havaittavissa oleva > getNextPageUsersObservable (lopullinen
    Lista  userList) {
    
    Havaittavissa oleva > usersPageObservable =
        Observable.just (Userlist);
    int lastUserId = getLastUserId (userList);
    Havaittavissa oleva > nextUsersPageObservable =
        getUsersObservable (lastUserId);
    return Observable.merge (seuraavaUsersPageObservable,
        usersPageObservable);
}
yksityinen boolean isLastPage (lopullinen luettelo  userList) {
    palauta userList.isEmpty ();
}

Ensinnäkin pyydämme yhtä sivua ilman mitään parametreja (tai voit lisätä 0 tähän, riippuen sovellusliittymästäsi), sitten tarkistamme lopulistan ehdot - jos emme saavuttaneet loppua, pyydämme joitain uusia sivuja parametrilla viimeisestä pyynnöstä (se voi olla käyttäjän viimeinen tunnus tai uusimman kuvan päivämäärä tai muu) ja yhdistämme sen edelliseen havainnoitavissa olevaan. Jos saavutamme luettelon lopun, lopetamme.

# 5 kevyt RxBus

Jos käytät tapahtumaväylää projektissasi (riippumatta siitä, onko kyse Otto, Greenrobotin tapahtumabussi tai jotain muuta), saatat olla kiinnostunut toteuttamaan oman tapahtumabussisi - RxBus! Saatat kysyä, miksi keksitämme pyörän uudelleen sen sijaan, että käyttäisimme jotain, jonka joku muu teki?

No, kun näet, kuinka helppo toteuttaa oma EventBus RxJavan kanssa, voit harkita tämän asettamista sisäiseksi kirjastoksi. Olet riippumaton ulkoisen kirjaston muutoksista, joten voit säätää RxBusia tarpeitasi vastaavasti ja - jos sinulla on jo RxJava projektissa - miksi et käytä sitä jotain muuta?

julkinen luokka RxBus {
    yksityinen staattinen lopullinen RxBus-esimerkki = uusi RxBus ();
    yksityinen lopullinen aihe  rxBus;
    julkinen RxBus () {
        PublishSubject  rxEventPublishSubject =
            PublishSubject.create ();
        rxBus = rxEventPublishSubject.toSerialized ();
    }
    julkinen staattinen RxBus getInstance () {
        paluutapahtuma;
    }
    julkinen havaittavissa oleva  getRxBus () {
        paluu rxBus;
    }
    julkinen mitätön viesti (lopullinen RxEvent rxEvent) {
        rxBus.onNext (rxEvent);
    }
    julkisen luokan RxEvent {}
}

RxBusin tärkein ”ydin” on SerializedSubject (hyvin samanlainen kuin PublishSubject, jota havaitsimme kaksoisnapsautuksilla, mutta tämä on lankavarma). Luomme yksinkertaisesti singleton-luokan, jossa on viittaus tähän SerializedSubject-aiheeseen. Jos lähetämme jonkin tapahtuman, säteilemme kohteita SerializedSubject-ohjelmalla. Jos tilaamme tapahtuman, tilaamme vastaanottaa tapahtumia SerializedSubject-ohjelmasta. Yksinkertainen, eikö niin? Käytämme toSerialized () -menetelmää, koska haluamme käyttää RxBus -laitetta eri säikeistä.

johtopäätös

Kuten näette - RxJavalla voi tehdä paljon asioita. Se on hyödyllinen näyttökertojen, tietojen pyytämisen ja sovelluksen sisäisen viestinnän kannalta. Muista, että esittämiin ongelmiin on monia ratkaisuja, ja RxJava ei välttämättä ole aina paras, mutta toivon, että nämä vinkit inspiroivat sinua etsimään joitain muita ratkaisuja ongelmiin.

Se siitä! Toivottavasti pidät neuvoistani. Pysy kuulolla lisää!