Comment faire plus Android Rx - 5 trucs et astuces

Si vous utilisez RxJava dans votre routine quotidienne, vous atteindrez probablement le jour où vous souhaitez… mettre RxJava partout! Laissez-moi vous donner 5 conseils pratiques.

Utiliser RxJava partout n'est pas une mauvaise idée (généralement). C’est normal que vous pensiez «Hé, c’est beaucoup plus cool si je pouvais simplement mettre cela dans le flux RxJava, au lieu d’utiliser for-loop / Handler / Async Task / une autre solution moche». Oui, ça va être cool. Si seulement je pouvais…

Eh bien, j’ai une bonne nouvelle pour vous: avec RxJava, vous pouvez réaliser la plupart des choses dont vous avez toujours rêvé! Laissez-moi vous donner mes 5 conseils sur les choses que j’aime et que j’utilise souvent dans mes projets.

Ces extraits de code fonctionneront à la fois sur RxJava et sur RxJava2. Cet article suppose que vous avez des connaissances de base sur RxJava. Sinon, je vous recommande de lire d’abord d’autres articles (celui-ci sur RxJava - la ligne de production - est un bon début).

# 1 Détection de double clic

Vous avez des boutons dans votre application et vous souhaitez détecter si ces boutons ont été cliqués deux fois. Facile, n'est-ce pas? Oui, tout ce que vous avez à faire est de faire un compteur, vérifiez chaque clic, déplacez le compteur d’une incrémentation vers le haut et rappelez-vous de le réinitialiser par la suite… Aucune façon, il doit y avoir une façon plus propre de le faire. Bien sûr, la voici:

private PublishSubject  eventSubject = PublishSubject.create ();
public static final int TIME_BETWEEN_EVENTS_MILLIS = 500;
public static final int NUMBER_OF_EVENTS = 2;
public DoubleClick () {
    eventSubject
        .buffer (eventSubject.debounce (TIME_BETWEEN_EVENTS_MILLIS,
            TimeUnit.MILLISECONDS))
        .filter (events -> events.size () == NUMBER_OF_EVENTS)
        .subscribe (événements -> doQuelque chose ());
    button.setOnClickListener ((bouton) ->
        eventSubject.onNext (true));
}

En utilisant PublishSubject, nous pouvons émettre nos propres éléments et les attraper. Après avoir attrapé, nous vérifions si le nombre d'événements est le même que la valeur que nous voulons. Bien sûr, vous pouvez le faire avec chaque événement - obtenir un texte de TextView, obtenir des clics à partir de n'importe quelle autre vue ou autre.

# 2 Répéter les demandes à l'API toutes les 10 minutes

L'utilisation de répétition par l'opérateur, combinée aux résultats de retard, peut entraîner un retard de notre abonnement après un certain temps. Si, pour une raison quelconque, vous souhaitez demander de nouvelles données à l'API toutes les 10 minutes, vous pouvez le faire avec RxJava en une seule ligne:

sourceObservable.repeatWhen (terminé -> terminé.delay (10,
    TimeUnit.MINUTES));

N'oubliez pas que cet observable ne se répète que si le précédent a été terminé.

# 3 Combinant deux objets dépendants

Disons que nous recevons des chats de l’API et que, pour chaque chat, nous aimerions obtenir des jouets (qui dépendent de Cat). Après cela, nous voulons combiner un objet avec CatAndToys. Il est possible de le faire avec RxJava en utilisant le deuxième paramètre de flatMap (ce qui n’est pas aussi couramment utilisé), qui

[…] Combine les éléments de l'observable source avec l'observable déclenché par ces éléments source, émettant ces combinaisons.

Source: documentation RxJava

Laissez le code parler pour lui-même:

Observable  catWithToysObservable =
    getCatObservable ()
        .flatMap ((cat) -> getToysForCatObservable (chat),
            (chat, jouets) -> nouveau CatWithToys (chat, jouets));

Nous voyons que ce premier paramètre dans flatMap prend Cat en tant que paramètre et renvoie Toys. Ensuite, le deuxième paramètre prend Cat et Toys (le résultat de la première fonction) et retourne l'objet CatWithToys. De cette façon, vous pouvez combiner de nombreuses demandes dépendantes à l'API sans utiliser d'opérateurs imbriqués flatMap.

# 4 Demande de pagination

Si vous souhaitez paginer certains objets à partir de l'API, vous pouvez le faire facilement avec RxJava. L'astuce consiste à fusionner toutes les pages jusqu'à atteindre un dernier point (par exemple, la dernière demande donne des résultats vides ou le nombre d'éléments est correct et correct). Regardons le code:

public Observable > getAllUsers () {
    getUsersObservable (null);
}
private Observable > getUsersObservable (final String
    lastUserId) {
    retourne apiAdapter
        .getData (lastUserId)
        .filter (userList ->! isLastPage (userList))
        .flatMap (this :: getNextPageUsersObservable);
}
private Observable > getNextPageUsersObservable (final
    Liste  userList) {
    
    Observable > usersPageObservable =
        Observable.just (userList);
    int lastUserId = getLastUserId (userList);
    Observable > nextUsersPageObservable =
        getUsersObservable (lastUserId);
    return Observable.merge (nextUsersPageObservable,
        utilisateursPageObservable);
}
private boolean isLastPage (Liste finale  userList) {
    return userList.isEmpty ();
}

Premièrement, nous demandons une seule page sans aucun paramètre (ou vous pouvez mettre 0 ici, en fonction de votre API), puis nous vérifions l'état de notre liste de fin - si nous n'atteignons pas la fin, nous demandons quelques les nouvelles pages avec le paramètre de la dernière demande (il peut s'agir du dernier identifiant de l'utilisateur, ou de la date de la dernière photo, ou autre) et nous le fusionnerons avec l'observable précédent. Si nous arrivons à la fin de la liste, nous finissons.

# 5 RxBus léger

Si vous utilisez un bus d’événement dans votre projet (qu’il s’agisse d’Otto, d’un bus d’événement de Greenrobot ou de quelque chose d’autre), vous voudrez peut-être mettre en œuvre votre propre bus d’événement - RxBus! Vous vous demandez peut-être pourquoi nous réinventons la roue au lieu d’utiliser quelque chose qui a été fabriqué par quelqu'un d’autre?

Eh bien, quand vous verrez à quel point il est facile d'implémenter votre propre EventBus avec RxJava, vous pouvez repenser à le faire en tant que bibliothèque interne. Vous êtes indépendant des modifications apportées à la bibliothèque externe, vous pouvez donc adapter RxBus à vos besoins et, si vous avez déjà RxJava dans le projet, pourquoi ne l'utilisez-vous pas pour autre chose?

classe publique RxBus {
    Instance RxBus finale privée et statique = new RxBus ();
    Objet final privé  rxBus;
    public RxBus () {
        PublishSubject  rxEventPublishSubject =
            PublishSubject.create ();
        rxBus = rxEventPublishSubject.toSerialized ();
    }
    public statique RxBus getInstance () {
        instance de retour;
    }
    public Observable  getRxBus () {
        renvoyer rxBus;
    }
    post vide public (final RxEvent rxEvent) {
        rxBus.onNext (rxEvent);
    }
    Classe publique RxEvent {}
}

Le "noyau" principal de RxBus est SerializedSubject (très similaire à PublishSubject, qui permettait de détecter les doubles clics, mais celui-ci est thread-safe). Nous créons simplement une classe singleton qui contient une référence à ce SerializedSubject. Si nous envoyons un événement, nous émettons des éléments avec SerializedSubject, si nous nous abonnons à l'événement, nous nous abonnons pour recevoir des événements provenant de SerializedSubject. Simple, n'est-ce pas? Nous utilisons la méthode toSerialized () parce que nous voulons utiliser notre RxBus à partir de différents threads.

Conclusion

Comme vous pouvez le constater, RxJava permet de faire beaucoup de choses. C’est utile pour les vues, la demande de données et la communication interne dans votre application. N'oubliez pas qu'il existe de nombreuses solutions aux problèmes que j'ai présentés et que RxJava n'est peut-être pas toujours la meilleure, mais j'espère que ces conseils vous ont incité à rechercher d'autres solutions à vos problèmes.

C'est tout! J'espère que vous aimez mes conseils. Restez à l'écoute pour plus!