Kuidas Androidi veelgi Rx-i muuta - 5 näpunäidet ja näpunäidet

Kui kasutate RxJavat oma igapäevases rutiinis, jõuate tõenäoliselt ühel päeval punkti, kuhu soovite ... pange RxJava kõikjale! Lubage mul anda teile 5 praktilist nõu.

RxJava kasutamine kõikjal pole halb mõte (tavaliselt). Tavaline on see, et mõtled: "Kuule, see näeb palju lahedam välja, kui saaksin selle lihtsalt RxJava voogu lisada, selle asemel et kasutada silmuse / käitleja / Asynci ülesannet / mõnda muud koledat lahendust". Jah, see saab olema lahe. Kui ainult saaksin ...

Noh, mul on teile mõned head uudised - saate RxJava abil teha enamiku asju, millest olete kunagi unistanud! Lubage mul anda teile oma 5 nõuannet asjade kohta, mis mulle meeldivad ja mida ma oma projektides sageli kasutan.

Need koodilõigud töötavad nii RxJava kui ka RxJava2. See artikkel eeldab, et teil on mõned põhiteadmised RxJava kohta. Kui ei, siis soovitan teil kõigepealt läbi lugeda mõned muud artiklid (see RxJava kohta - tootmisliin - pakub suurepärast algust).

# 1 Topeltklõpsu tuvastamine

Teie rakenduses on mõned nupud ja soovite tuvastada, kas neid nuppe klõpsati kaks korda. Lihtne, kas pole? Jah, kõik, mida selleks vajate, on loenduri tegemine, iga klõpsu kontrollimine, loenduri sammu võrra ülespoole tõstmine ja loenduri lähtestamine. Pärast seda peab olema puhtam viis. Muidugi, siin see on:

privaatne PublishSubject  eventSubject = PublishSubject.create ();
avalik staatiline lõplik int TIME_BETWEEN_EVENTS_MILLIS = 500;
avalik staatiline lõplik int NUMBER_OF_EVENTS = 2;
avalik DoubleClick () {
    sündmus
        .puffer (eventSubject.debounce (TIME_BETWEEN_EVENTS_MILLIS,
            TimeUnit.MILLISECONDS))
        .filter (sündmused -> sündmused.suurus () == NUMBER_OF_EVENTS)
        .tellimine (sündmused -> doSomething ());
    nuppu.setOnClickListener ((nupp) ->
        eventSubject.onNext (true));
}

PublishSubjecti kasutades saame emiteerida oma üksused ja neid kinni püüda. Pärast püüdmist kontrollime, kas sündmuste arv on sama, mis meie soovitud väärtus. Muidugi saate seda teha iga sündmusega - teksti hankimiseks TextView-st, klõpsude saamiseks mis tahes muust vaatest või muust.

# 2 API-taotluste kordamine iga 10 minuti järel

Operaatori korduse kasutamineKui koos viivituste tulemustega võib mõne aja pärast meie liitumine viivitada. Kui soovite mingil põhjusel taotleda API-lt iga 10 minuti tagant uusi andmeid, saate seda teha RxJava abil ainult ühes reas:

sourceObservable.repeatWhen (valmis -> complete.delay (10,
    TimeUnit.MINUTES));

Pidage ainult meeles, et jälgitav kordub ainult siis, kui eelmine sai valmis.

# 3 Kahe sõltuva objekti ühendamine

Oletame, et võtame kasse API-st ja tahaksime iga kassi jaoks hankida mänguasju (mis sõltuvad kassist). Pärast seda soovime saada objekti, mis oleks ühendatud CatAndToys'iga - seda on võimalik teha RxJava abil, kasutades flatMap'i teist parameetrit (mida veel nii tihti ei kasutata), mida

[…] Ühendab vaatlusallikast pärinevad üksused nende lähteallikate käivitatava jälgitavaga, eraldades need kombinatsioonid.

Allikas: RxJava dokumentatsioon

Las kood räägib enda eest:

Vaadeldav  catWithToysObservable =
    getCatObservable ()
        .flatMap ((kass) -> getToysForCatObservable (kass),
            (kass, mänguasjad) -> uued CatWithToys (kass, mänguasjad));

Näeme seda esimest parameetrit flatMapis, võttes parameetriks Kassi ja tagastades mänguasjad. Seejärel võtab teine ​​parameeter kassi ja mänguasjad (esimese funktsiooni tulemus) ja tagastab objekti CatWithToys. Nii saate kombineerida paljusid sõltuvaid taotlusi API-le ilma pesastatud flatMap-operaatoreid kasutamata.

# 4 taotlege lehtimist

Kui soovite mõne API kaudu objekti pagineerida, saate seda RxJava abil hõlpsalt teha. Trikk on kõigi lehtede liitmine, kuni saavutate mingi lõpppunkti (nt viimane taotlus annab teile tühjad tulemused, vastasel juhul on üksuste arv korrektne ja korrektne). Vaatame koodi:

avalik jälgitav > getAllUsers () {
    return getUsersObservable (null);
}
privaatne jälgitav > getUsersObservable (viimane
    lastUserId) {
    tagasta apiAdapter
        .getData (lastUserId)
        .filter (userList ->! isLastPage (userList))
        .flatMap (see :: getNextPageUsersObservable);
}
privaatne jälgitav > getNextPageUsersObservable (lõplik
    Loendi  kasutajaloend) {
    
    Vaatlusväärne > usersPageObservable =
        Observable.just (userList);
    int lastUserId = getLastUserId (userList);
    Vaatlusalune > järgmineUsersPageObservable =
        getUsersObservable (lastUserId);
    return Observable.merge (nextUsersPageObservable,
        usersPageObservable);
}
privaatne boolean isLastPage (lõplik loend  userList) {
    tagastama userList.isEmpty ();
}

Esiteks taotleme ühe lehe kuvamist ilma ühegi parameetrita (või võite siia lisada 0, sõltuvalt teie API-st), siis kontrollime oma lõpploendi tingimust - kui me lõppu ei jõudnud, taotleme uued lehed parameetriga viimasest taotlusest (see võib olla kasutaja viimane ID või uuema foto kuupäev või midagi muud) ja me ühendame selle eelmise jälgitavaga. Kui jõuame nimekirja lõppu, lõpetame.

# 5 kerge RxBus

Kui kasutate oma projektis sündmusbussi (ükskõik, kas see on Otto, Greenroboti ürituste buss või midagi muud), võite olla huvitatud oma sündmusbussi - RxBus - juurutamisest! Võib-olla küsite, miks leiutame ratta uuesti, selle asemel, et kasutada midagi, mille tegi keegi teine?

Noh, kui näete, kui lihtne on teie EventBusi RxJava abil rakendada, võite mõelda selle sisemiseks teegiks panemiseks. Olete sõltumatu välise raamatukogu muudatustest, nii et saate RxBusit oma vajadustele kohandada ja - kui teil on RxJava juba projektis - miks te seda veel millekski ei kasuta?

avaliku klassi RxBus {
    privaatne staatiline lõplik RxBus-eksemplar = uus RxBus ();
    privaatne lõplik subjekt  rxBus;
    avalik RxBus () {
        PublishSubject  rxEventPublishSubject =
            PublishSubject.create ();
        rxBus = rxEventPublishSubject.toSerialized ();
    }
    avalik staatiline RxBus getInstance () {
        tagastamise eksemplar;
    }
    avalik jälgitav  getRxBus () {
        tagasi rxBus;
    }
    avalik tühine postitus (lõplik RxEvent rxEvent) {
        rxBus.onNext (rxEvent);
    }
    avaliku klassi RxEvent {}
}

RxBusi peamine “tuum” on SerializedSubject (väga sarnane PublishSubject'iga, mida kasutasime topeltklõpsude tuvastamiseks, kuid see on niidikindel). Loome lihtsalt singletoniklassi, millel on viide sellele SerializedSubject'ile. Kui saadame mõne sündmuse, siis väljastame üksusi SerializedSubjectiga, kui tellime sündmuse, tellime sündmuste vastuvõtmise SerializedSubjectist. Lihtne, kas pole? Me kasutame meetodit toSerialized (), kuna tahame kasutada oma RxBusi erinevatest lõimest.

Järeldus

Nagu näete - RxJavaga saab teha palju asju. See on abiks teie rakenduses vaadete, andmete taotlemise ja sisemise suhtluse jaoks. Pidage meeles, et minu esitatud probleemidele on palju lahendusi ja RxJava ei pruugi alati olla parim, kuid loodan, et need näpunäited inspireerisid teid oma probleemidele muid lahendusi otsima.

See selleks! Loodan, et teile meeldivad minu näpunäited. Olge rohkem kursis!