[JAVA] Gestion des événements avec RxBus sur Android

introduction

Jusqu'à la dernière fois, j'ai obtenu les données de l'API et je les ai apportées à ViewModel. Cette fois, je vais vous expliquer la partie à apporter de ViewModel à View, le traitement des événements.

Conditions préalables

Veuillez vous référer à ici pour les prérequis du code expliqué ici.

À propos de la nécessité du traitement des événements

ViewModel doit notifier à View (activité et fragment) le résultat du traitement asynchrone (tel que l'api). À ce stade, si la valeur de retour est reçue dans le traitement synchrone, le thread principal sera gelé. En outre, si le ViewModel a une référence de vue, le ViewModel doit être conscient du cycle de vie, et View n'est pas nécessaire car View est requis pour le test unitaire de ViewModel. Par conséquent, j'utilise un événement pour le recevoir uniquement lorsque la vue est active.

Raisons de choisir RxBus.

EventBus est une bibliothèque bien connue pour gérer les événements. La raison d'utiliser RxBus cette fois est Il y avait une histoire que la notification d'EventBus était difficile à comprendre, alors j'ai choisi RxBus.

En effet, EventBus enregistre les événements globalement, En regardant maintenant, il semble que cela dépend de la mise en œuvre comme suit. https://qiita.com/subaru44k/items/27cd4828edc65cd9d7a6

En ce sens, EventBus aurait pu être bon compte tenu du coût d'apprentissage, Un autre avantage de l'utilisation de RxBus est que les bibliothèques utilisées peuvent être intégrées avec un traitement asynchrone. Il n'y a aucune raison d'utiliser RxBus simplement parce que vous utilisez RxJava. RxJava et EventBus sont également OK.

Je pense que cette zone doit être choisie en fonction de la situation de l'équipe.

Mécanisme d'événement par RxBus

Dans RxBus, en accédant à la même instance RxBus sur le lieu d'utilisation (par exemple, View et ViewModel), Il permet l'échange d'événements. J'essaye d'obtenir une instance de RxBus dans une seule tonne. L'enregistrement et la surveillance des événements peuvent désormais être faiblement couplés de n'importe où.

Au départ, Application avait une instance, Lorsque j'exécute un test unitaire, je ne peux pas l'exécuter car je n'ai pas d'application, j'ai donc choisi singleton. Si vous exécutez le test avec Android Test, cela fonctionnera, alors je me demande si tout allait bien, J'utilise une seule tonne maintenant.

RxBus et cycle de vie

Lorsque vous l'utilisez dans View, si vous ne libérez pas l'événement enregistré tout au long du cycle de vie, Cela peut fuir ou entraîner une erreur sans référence. Les détails seront expliqués plus tard, mais lorsque l'activité ou le fragment se retourne ou est libéré, Vous devez également annuler le suivi de l'événement.

Exemple de code

Implémentation RxBus.

Tout d'abord, définissez RxBus. La source est ici.

    public class RxBus {
        private final PublishSubject<Object> bus = PublishSubject.create();
        private static RxBus rxBus;
    
        private RxBus() {
    
        }
    
        public static RxBus getInstance() {
            if (rxBus == null) {
                rxBus = new RxBus();
            }
            return rxBus;
        }
    
        public void send(final Object event) {
            bus.onNext(event);
        }
    
        public Observable<Object> toObservable() {
            return bus;
        }
    
        public boolean hasObservers() {
            return bus.hasObservers();
        }
    }

Définissez une instance de PublishSubject qui enregistre réellement l'événement, Défini pour renvoyer sa propre instance en tant que singleton.

Exemple d'envoi d'un événement avec RxBus

C'est un processus qui utilise réellement RxBus et transmet le résultat obtenu de manière asynchrone de l'API à View. La source est ici.

    GithubRepositoryApiCompleteEventEntity eventResult = new GithubRepositoryApiCompleteEventEntity();
    eventResult.setListItems(data);
    if (response.getItems() != null && response.getItems().size() > 0) {
            eventResult.setResult(true);
    }
    
    //Appeler un événement
    RxBus.getInstance().send(eventResult);

Les données acquises dans l'entité utilisée pour échanger des événements appelés GithubRepositoryApiCompleteEventEntity et le résultat de l'acquisition sont stockés. Spécifiez cette instance comme argument de l'événement et envoyez l'événement.

Exemple de réception d'un événement avec RxBus

C'est un processus pour recevoir l'événement envoyé par RxBus. La source est ici.

            this.compositeDisposable = new CompositeDisposable();
            this.compositeDisposable.add(RxBus.getInstance()
                    .toObservable()
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Object>() {
                        @Override
                        public void accept(Object obj) {
                            if (obj instanceof GithubRepositoryApiCompleteEventEntity) {
                                //Liste des résultats
                                if (((GithubRepositoryApiCompleteEventEntity) obj).isResult()) {
                                    RecyclerView list = view.findViewById(R.id.githubRepositoryList);
                                    list.setLayoutManager(new LinearLayoutManager(view.getContext()));
                                    list.setAdapter(new GithubRepositoryListAdapter(((GithubRepositoryApiCompleteEventEntity) obj).getListItems()));
                                    list.setVisibility(View.VISIBLE);
                                    list.addItemDecoration(new DividerItemDecoration(view.getContext(), DividerItemDecoration.VERTICAL));
                                }
                                view.findViewById(R.id.progressBar).setVisibility(View.GONE);
                            }
                            //Ne gérez pas d'autres événements
                        }
                    }));
    
            ExpApplication.getInstance().getViewModelLocator().getGithubRepositoryListViewModel().getRepositoryListData();
            
    //~ Omis ~
            
        @Override
        public void onStop() {
            super.onStop();
            this.compositeDisposable.clear();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            this.compositeDisposable.clear();
        }

Définissez une instance de CompositeDisposable et Réglez le traitement de réception d'événement RxBus sur ce paramètre. En appelant CompositeDisposable.clear () avec onStop () ou onDestroy () et en annulant la surveillance, Il peut être traité tout au long du cycle de vie.

Traitement de la réception des événements RxBus après avoir appelé .toObservable () Spécifie le thread à traiter avec .observeOn (AndroidSchedulers.mainThread ()). Depuis que je joue avec l'écran, j'utilise le fil principal cette fois, Vous pouvez également l'exécuter dans un thread différent de Main avec Schedulers.newThread (). .subscribe (new Consumer <Object> () { Le processus de réception spécifique est décrit après.

public void accept (Object obj) { Ce qui suit est le processus de réception, L'argument spécifié dans le processus de transmission est envoyé en tant que variable de type Object. ʻIf (obj instanceof GithubRepositoryApiCompleteEventEntity) {`déterminer le type et Il est déterminé s'il s'agit de l'événement que vous souhaitez recevoir. S'il s'agit d'un événement à recevoir, il sera traité.

en conclusion

Alors, j'ai essayé d'expliquer RxBus. La prochaine fois, j'aimerais expliquer sqLite par pièce.

Recommended Posts

Gestion des événements avec RxBus sur Android
Compatible avec Android 10 (API 29)
[Android] Notes sur xml
Base de données Firebase-Realtime sur Android pouvant être utilisée avec copie
Personnaliser la vue de liste sur Android
Bibliothèque de transmission en plusieurs parties sur Android
Utiliser la communication série sur Android
Développement d'applications ROS sur Android
Utiliser le code natif sur Android
RxJava (RxAndroid) + RxBus + Data Binding + échantillon de salle (basé sur Java 1.7) sur Android.