229 votes

Quand utiliser RxJava dans Android et quand utiliser LiveData des composants architecturaux Android ?

Je ne comprends pas la raison d'utiliser RxJava dans Android et LiveData dans Android Architectural Components. Il serait vraiment utile que les cas d'utilisation et les différences entre les deux soient expliqués avec un exemple sous forme de code qui explique les différences entre les deux.

8 votes

Vous avez trouvé une bonne raison ? Je me pose la même question...

144voto

paiNie Points 2716

En ce qui concerne la question initiale, RxJava et LiveData se complètent très bien.

LiveData brille sur la couche ViewModel, avec son intégration étroite avec les cycles de vie d'Android et ViewModel . RxJava fournit plus de capacités dans les transformations (comme mentionné par @Bob Dalgleish).

Actuellement, nous utilisons RxJava dans les couches de sources de données et de référentiels, et il est transformé en LiveData (en utilisant LiveDataReactiveStreams ) dans les ViewModels (avant d'exposer les données aux activités/fragments) - cette approche me convient parfaitement.

12 votes

Si nous vous avons bien compris, LiveData n'est utile que pour les implémentations spécifiques à l'interface utilisateur d'Android. Si nous construisons simplement une application générique avec une architecture propre, et que nous partageons cette architecture avec d'autres plateformes, alors RxJava est plus adapté que LiveData ?

1 votes

@IgorGanapolsky quel langage/frameworks utilisez-vous pour les applications génériques ?

0 votes

Des API indépendantes d'Android et une architecture propre écrite en Java/Kotlin.

134voto

Bob Dalgleish Points 1294

Android LiveData est une variante du modèle d'observateur original, avec l'ajout de transitions actif/inactif. En tant que tel, il est très restrictif dans sa portée.

En utilisant l'exemple décrit dans Android LiveData Une classe est créée pour surveiller les données de localisation, et s'enregistrer et se désenregistrer en fonction de l'état de l'application.

RxJava fournit des opérateurs qui sont beaucoup plus généralisés. Supposons que cet observable fournisse des données de localisation :

Observable<LocationData> locationObservable;

L'implémentation de l'observable peut être construite à l'aide de Observable.create() pour mettre en correspondance les opérations de rappel. Lorsque l'observable est souscrit, le rappel est enregistré, et lorsqu'il est désabonné, le rappel est désenregistré. L'implémentation ressemble beaucoup au code fourni dans l'exemple.

Supposons également que vous disposez d'un observable qui émet true lorsque l'application est active :

Observable<Boolean> isActive;

Vous pouvez alors fournir toutes les fonctionnalités de LiveData de la manière suivante

Observable<LocationData> liveLocation =
  isActive
    .switchMap( active -> active ? locationObservable : Observable.never() );

Le site switchMap() fournira soit l'emplacement actuel sous forme de flux, soit rien si l'application n'est pas active. Une fois que vous avez le liveLocation observable, il y a beaucoup de choses que vous pouvez faire avec lui en utilisant les opérateurs RxJava. Mon exemple préféré est le suivant :

liveLocation.distinctUntilChanged()
  .filter( location -> isLocationInAreaOfInterest( location ) )
  .subscribe( location -> doSomethingWithNewLocation( location ) );

Cela n'exécutera l'action que lorsque l'emplacement a changé, et l'emplacement est intéressant. Vous pouvez créer des opérations similaires qui combinent des opérateurs de temps pour déterminer la vitesse. Plus important encore, vous pouvez contrôler en détail si les opérations se déroulent dans le thread principal, dans un thread d'arrière-plan ou dans plusieurs threads, en utilisant les opérateurs RxJava.

L'intérêt de RxJava est qu'il combine le contrôle et la synchronisation dans un seul univers, en utilisant des opérations fournies par la bibliothèque, ou même des opérations personnalisées que vous fournissez.

LiveData ne traite qu'une petite partie de cet univers, l'équivalent de la construction de la liveLocation .

2 votes

Merci, la documentation de LiveData ne semble plus faire référence à un échantillon d'emplacement. Il y a des points plus intéressants (avec un échantillon d'emplacement) ici : androidkt.com/livedata

5 votes

@DanielWilson le lien n'est plus disponible.

1 votes

Mec, je ne me souviens pas de ce qu'il y avait sur ce lien :D J'aime l'exemple de code de Mark Allison pour les données en direct : blog.stylingandroid.com/architecture-components-livedata

124voto

Abhishek Kumar Points 167

Il existe de nombreuses différences entre LiveData et RxJava :

  1. LiveData n'est pas un STREAM alors qu'en RxJava, tout (littéralement tout) est une STREAM .
  2. LiveData est une classe de support de données observable. Contrairement à un observable classique, LiveData tient compte du cycle de vie, ce qui signifie qu'il respecte le cycle de vie des autres composants d'application, tels que les activités, les fragments ou les services. Cette prise de conscience garantit que LiveData ne met à jour que les observateurs de composants d'application qui sont dans un état de cycle de vie actif.
  3. LiveData est synchrone Vous ne pouvez donc pas exécuter un morceau de code (appel réseau, manipulation de base de données, etc.) de manière asynchrone en utilisant uniquement LiveData comme vous le faites avec RxJava.
  4. Le mieux que vous puissiez faire pour exploiter au mieux ce duo est d'utiliser RxJava pour votre logique d'entreprise (appel réseau, manipulation de données, etc.), tout ce qui se passe dans et au-delà du Référentiel ) et utilisez LiveData pour votre couche de présentation. Ainsi, vous bénéficiez de capacités de transformation et de flux pour votre logique métier et d'un fonctionnement tenant compte du cycle de vie pour votre interface utilisateur.
  5. LiveData et RxJava se complètent mutuellement si elles sont utilisées ensemble. Ce que je veux dire, c'est que vous pouvez tout faire avec RxJava et à la fin, lorsque vous voulez mettre à jour l'interface utilisateur, faites quelque chose comme le code ci-dessous pour transformer votre Observable en LiveData. Ainsi, votre vue (UI) observe la LiveData dans le ViewModel où votre LiveData n'est rien d'autre qu'une MutableLiveData non-mutable (ou MutableLiveData est une LiveData mutable).
  6. La question est donc de savoir pourquoi utiliser LiveData en premier lieu. Comme vous pouvez le voir ci-dessous dans le code, vous stockez votre réponse de RxJava dans MutableLiveData (ou LiveData) et votre LiveData tient compte du cycle de vie, donc d'une certaine manière, vos données tiennent compte du cycle de vie. Maintenant, imaginez la possibilité que vos données elles-mêmes sachent quand et quand ne pas mettre à jour l'interface utilisateur.
  7. LiveData n'a pas d'historique (seulement l'état actuel). Par conséquent, vous ne devriez pas utiliser LiveData pour une application de chat.
  8. Quand vous utilisez LiveData avec RxJava, vous n'avez pas besoin de choses comme MediatorLiveData , SwitchMap etc. Ce sont des outils de contrôle des flux et RxJava est bien meilleur à ce niveau.
  9. Considérez LiveData comme un support de données et rien d'autre. Nous pouvons également dire que LiveData est un consommateur conscient du cycle de vie.

    public class RegistrationViewModel extends ViewModel {
        Disposable disposable;

        private RegistrationRepo registrationRepo;
        private MutableLiveData<RegistrationResponse> modelMutableLiveData =
                new MutableLiveData<>();

        public RegistrationViewModel() {
        }

        public RegistrationViewModel(RegistrationRepo registrationRepo) {
            this.registrationRepo = registrationRepo;
        }

        public void init(RegistrationModel registrationModel) {
            disposable = registrationRepo.loginForUser(registrationModel)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Response<RegistrationResponse>>() {
                        @Override
                        public void accept(Response<RegistrationResponse>
                                                   registrationModelResponse) throws Exception {

                            modelMutableLiveData.setValue(registrationModelResponse.body());
                        }
                    });
        }

        public LiveData<RegistrationResponse> getModelLiveData() {
            return modelMutableLiveData;
        }

       @Override
       protected void onCleared() {
                super.onCleared();
            disposable.dispose();
         }
    }

8 votes

Voir LiveData comme un support de données et rien d'autre. ==> OUI

4 votes

Bel exemple. Vous avez oublié de déclarer les jetables et il serait bien de les effacer dans onCleared .

0 votes

Pouvez-vous expliquer comment livedata est synchrone ? Pour autant que je sache, nous pouvons envoyer l'objet Livedata à un autre thread et ensuite ce thread peut poster une valeur que l'observateur peut écouter dans le MainThread.

33voto

Ali Nem Points 1508

En fait, LiveData n'est pas un outil essentiellement différent de RxJava Alors pourquoi a-t-il été introduit en tant que composant de l'architecture alors qu'il s'agit d'un composant de l'architecture. RxJava aurait pu facilement gérer le cycle de vie en stockant toutes les souscriptions à des observables dans un fichier CompositeDispoable et ensuite les jeter dans onDestroy() de la Activity ou onDestroyView() de la Fragment en utilisant une seule ligne de code ?

J'ai répondu à cette question en construisant une application de recherche de films à l'aide de RxJava, puis de LiveData. aquí .

En résumé, oui, c'est possible, mais il faudrait d'abord remplacer les méthodes de cycle de vie pertinentes, en plus de posséder les connaissances de base sur le cycle de vie. Cela n'a peut-être toujours pas de sens pour certains, mais le fait est que, selon l'un des experts de l Sessions Jetpack à la Google I/O 2018 de nombreux développeurs trouvent la gestion du cycle de vie complexe. Les erreurs de plantage dues à l'absence de gestion de la dépendance du cycle de vie peuvent être un autre signe que certains développeurs, même s'ils connaissent le cycle de vie, oublient d'en tenir compte dans chaque activité/fragment qu'ils utilisent dans leur application. Dans les grandes applications, cela pourrait devenir un problème, sans compter l'effet négatif que cela pourrait avoir sur la productivité.

L'essentiel est qu'en introduisant LiveData On s'attend à ce qu'un grand nombre de développeurs adoptent MVVM sans même avoir à comprendre la gestion du cycle de vie, les fuites de mémoire et les pannes. Même si je n'ai aucun doute sur le fait que LiveData n'est pas comparable à RxJava en termes de capacités et du pouvoir qu'elle donne aux développeurs, la programmation réactive et la RxJava est un concept et un outil difficile à comprendre pour beaucoup. D'un autre côté, je ne pense pas que LiveData est censé être un remplacement pour RxJava -Mais il s'agit d'un outil très simple permettant de gérer un problème controversé et répandu chez de nombreux développeurs.

** MISE À JOUR ** J'ai ajouté un nouvel article aquí où j'ai expliqué comment une mauvaise utilisation de LiveData peut conduire à des résultats inattendus. RxJava peut venir à la rescousse dans ces situations


2 votes

"pourquoi a-t-il été introduit alors que RxJava aurait pu facilement gérer le cycle de vie en stockant toutes les souscriptions dans un CompositeDispoable et en les éliminant ensuite dans onDestroy() de l'Activité" - LiveData disposerait dans onStop en fait

0 votes

@arekolek d'après ce que j'ai compris : même pour gérer le CompositeDispoable nous devons écraser les méthodes du cycle de vie. Mais dans Live data tout sera inclus dans une seule ligne de code. Nous économisons donc au moins 20 lignes de code.

0 votes

Nous pouvons définir un baseFragment et définir la méthode Disposable[] subscriptions() qui sera surchargée par tous les fragments dérivés, appeler cette méthode dans onCreateView et ajouter la valeur de retour dans un CompositeDisposable, disposer de celui-ci dans onDestroyView, plus d'oubli.

27voto

trocchietto Points 1423

Comme vous le savez peut-être, dans l'écosystème réactif, nous avons une Observable qui émet des données et un Observateur qui s'abonne (est notifié) de cette émission Observable, rien d'étrange à la façon dont fonctionne ce que l'on appelle le modèle Observer. Un Observable "crie" quelque chose, l'Observateur est notifié que l'Observable crie quelque chose à un moment donné.

Pensez à LiveData comme un Observable qui vous permet de gérer les Observateurs qui se trouvent dans une active l'état. En d'autres termes LiveData est un simple Observable mais aussi s'occupe du cycle de vie.

Mais voyons les deux cas de code que vous demandez :

A) Données en direct

B) RXJava

A) Il s'agit d'une implémentation de base de LiveData

1) vous instanciez habituellement LiveData dans le ViewModel pour maintenir le changement d'orientation (vous pouvez avoir LiveData qui est en lecture seule, ou MutableLiveData qui est en écriture, donc vous exposez habituellement à l'extérieur de la classe LiveData)

2) dans la OnCreate de la méthode Principal Activité (pas le ViewModel) vous "souscrivez" un objet Observer (généralement par une méthode onChanged)

3) vous lancez la méthode observée pour établir le lien

D'abord le ViewModel (possède la logique d'entreprise)

class ViewModel : ViewModel() { //Point 1

    var liveData: MutableLiveData<Int> = MutableLiveData()

}

Et c'est le MainActivity ( aussi stupide que possible )

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val ViewModelProvider= ViewModelProviders.of(this).get(ViewModel::class.java)

        ViewModelProvider.observe(this, Observer {//Points 2 and 3
            //what you want to observe
        })

        }
    }
}

B) Voici l'implémentation de base de RXJava

1) vous déclarez un Observable

2) vous déclarez un Observateur

3) vous abonnez l'Observable avec l'Observateur

Observable.just(1, 2, 3, 4, 5, 6) // Point 1

   .subscribe(new Subscriber() {    //Points 2 & 3
       @Override
       public void onCompleted() {
           System.out.println("Complete!");
       }

       @Override
       public void onError(Throwable e) {
       }

       @Override
       public void onNext(Double value) {
           System.out.println("onNext: " + value);
       }
    });

En particulier LiveData est utilisé avec Lifecycle et souvent avec ViewModel (comme nous l'avons vu) des composants d'architecture. En effet, lorsque LiveData est combinée avec un ViewModel vous permet pour tenir à jour en temps réel chaque changement dans l'observateur, afin que les événements soient gérés en temps réel là où cela est nécessaire. Pour utiliser LiveData est fortement recommandé pour connaître le concept de cycle de vie et les objets relatifs Propriétaire de LifeCycle/LifeCycle Je vous suggère également de jeter un coup d'œil à Transformations si vous voulez mettre en œuvre LiveData dans des scénarios de la vie réelle. Vous trouverez ici quelques cas d'utilisation de la grande commonsware .

Pour conclure En gros, LiveData est une version simplifiée RXJava RXJava, un moyen élégant d'observer les changements dans plusieurs composants sans créer de règles de dépendance explicites entre les composants, ce qui permet de tester plus facilement le code et de le rendre beaucoup plus lisible. RXJava, vous permet de faire les choses de LiveData et bien plus encore. Grâce aux fonctionnalités étendues de RXJava, vous pouvez à la fois utiliser LiveData pour des cas simples ou exploiter toute la puissance de RXJava en continuant à utiliser des composants de l'architecture Android comme le composant ViewModel bien sûr, cela signifie que RXJava peut être beaucoup plus complexe, il suffit de penser a des centaines d'opérateurs au lieu de SwitchMap et Map of LiveData(pour le moment).

RXJava version 2 est une bibliothèque qui a révolutionné le paradigme orienté objet, en ajoutant une manière dite fonctionnelle de gérer le flux du programme.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X