Quando utilizzare RxJava in Android e quando utilizzare LiveData da Android Architectural Components?


186

Non sto ottenendo il motivo per utilizzare RxJava in Android e LiveData da Android Architectural Components. Sarebbe davvero utile se i casi d'uso e le differenze tra i due siano spiegati insieme a un esempio di esempio sotto forma di codice che spiega le differenze tra i due.


6
Hai già trovato una buona ragione? Mi chiedo lo stesso ...
IgorGanapolsky,

Risposte:


117

Android LiveData è una variante del modello di osservatore originale, con l'aggiunta di transizioni attive / inattive. Come tale, ha un ambito molto restrittivo.

Utilizzando l'esempio descritto in Android LiveData , viene creata una classe per monitorare i dati sulla posizione e registrarsi e annullare la registrazione in base allo stato dell'applicazione.

RxJava fornisce operatori molto più generalizzati. Supponiamo che questo osservabile fornisca dati sulla posizione:

Observable<LocationData> locationObservable;

L'implementazione dell'osservabile può essere costruita usando Observable.create() per mappare le operazioni di richiamata. Quando l'osservabile viene sottoscritto, la richiamata viene registrata e quando viene annullata l'iscrizione, la richiamata non viene registrata. L'implementazione è molto simile al codice fornito nell'esempio.

Supponiamo anche che tu abbia un osservabile che emette vero quando l'applicazione è attiva:

Observable<Boolean> isActive;

Quindi è possibile fornire tutte le funzionalità di LiveData come segue

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

L' switchMap()operatore fornirà la posizione corrente come flusso o nulla se l'applicazione non è attiva. Una volta che hai l' liveLocationosservabile, ci sono molte cose che puoi fare usando gli operatori RxJava. Il mio esempio preferito è:

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

Ciò eseguirà l'azione solo quando la posizione è cambiata e la posizione è interessante. È possibile creare operazioni simili che combinano gli operatori di tempo per determinare la velocità. Ancora più importante, è possibile fornire un controllo dettagliato sull'esecuzione delle operazioni nel thread principale, in un thread in background o in più thread, utilizzando gli operatori RxJava.

Il punto di RxJava è che combina controllo e tempistica in un singolo universo, utilizzando le operazioni fornite dalla libreria o persino le operazioni personalizzate fornite dall'utente.

LiveData si occupa solo di una piccola parte di quell'universo, l'equivalente della costruzione di liveLocation.


2
Grazie, i documenti di LiveData non sembrano più fare riferimento a un campione di posizione. Ci sono altri punti interessanti (con un esempio di posizione) qui: androidkt.com/livedata
Daniel Wilson,

5
@DanielWilson il link non è più disponibile.
Tura,

Amico, non ricordo che il wtf fosse su quel link: DI come il codice di esempio di Mark Allison per un dato dal vivo: blog.stylingandroid.com/architecture-components-livedata
Daniel Wilson,

3
The point of RxJava is that it combines control and timing into a single universe, using operations provided from the library, or even custom operations that you provide. Ma il ciclo di vita di LiveData non è a conoscenza. Se dovessimo usare Rx, non dovremmo gestire i cambiamenti del ciclo di vita?
Sparker0i

@ Sparker0i punto qui. RxJava non è a conoscenza del ciclo di vita. dobbiamo gestire manualmente. dove come in LiveData è già curato il ciclo di vita.
Aks4125,

119

Per quanto riguarda la domanda originale, sia RxJava che LiveData si completano perfettamente.

LiveDatabrilla sul livello ViewModel, con la sua stretta integrazione con i cicli di vita di Android e ViewModel. RxJavaoffre maggiori capacità nelle trasformazioni (come menzionato da @Bob Dalgleish).

Attualmente, stiamo utilizzando RxJavalivelli di origine e repository di dati, ed è trasformato in LiveData(usando LiveDataReactiveStreams) in ViewModels (prima di esporre i dati ad attività / frammenti) - abbastanza soddisfatto di questo approccio.


8
Se ti abbiamo capito correttamente, LiveData è utile solo per implementazioni specifiche dell'interfaccia utente Android. Se stiamo solo creando un'app generica con Clean Architecture e condividendo questa architettura con altre piattaforme, allora RxJava è più adatto di LiveData?
IgorGanapolsky,

@IgorGanapolsky che lingua / framework usi per l'app generica?
kzotin,

API indipendenti da Android e Clean Arch scritte in Java / Kotlin.
IgorGanapolsky,

1
puoi suggerire qualche esempio funzionante di LiveDataReactiveStreams nella tua risposta?
Pawan,

2
@kzotin non ti serve observeOn, lo LiveDataReactiveStreamsfa comunque chiamando LiveData.postValue(). E non vi è alcuna garanzia subscribeOnche ciò avrà alcun effetto in generale.
Arekolek,

77

Esistono molte differenze tra LiveData e RxJava:

  1. LiveData non è uno STREAM mentre in RxJava tutto (letteralmente tutto) è uno STREAM .
  2. LiveData è una classe di dati titolare osservabile. A differenza di un normale osservabile, LiveData è consapevole del ciclo di vita, il che significa che rispetta il ciclo di vita di altri componenti dell'app, come attività, frammenti o servizi. Questa consapevolezza garantisce che LiveData aggiorni solo gli osservatori dei componenti dell'app che si trovano in uno stato del ciclo di vita attivo.
  3. LiveData è sincrono , quindi non è possibile eseguire un blocco di codice (chiamata di rete, manipolazione del database ecc.) In modo asincrono usando solo LiveData come si fa con RxJava.
  4. La cosa migliore che puoi fare per sfruttare al meglio questo duo è usare RxJava per la tua logica aziendale (chiamata di rete, manipolazione dei dati ecc., Qualsiasi cosa accada dentro e fuori il repository ) e usare LiveData per il tuo livello di presentazione. In questo modo, ottieni capacità di trasformazione e streaming per la tua logica aziendale e operazioni consapevoli del ciclo di vita della tua UI.
  5. LiveData e RxJava si completano a vicenda se usati insieme. Quello che voglio dire è, fare tutto con RxJava e alla fine quando si desidera aggiornare l'interfaccia utente, fare qualcosa come il codice indicato di seguito per cambiare il tuo osservabile in LiveData. Pertanto, View (UI) osserva LiveData in ViewModel in cui LiveData non è altro che MutableLiveData non mutabile (o MutableLiveData è LiveData mutabile).
  6. Quindi la domanda qui è, perché dovresti usare LiveData in primo luogo? Come puoi vedere di seguito nel codice, memorizzi la tua risposta da RxJava a MutableLiveData (o LiveData) e LiveData è consapevole del ciclo di vita, quindi in un certo senso i tuoi dati sono sensibili al ciclo di vita. Ora, immagina solo la possibilità quando i tuoi dati stessi sanno quando e quando-non-aggiornare l'interfaccia utente.
  7. LiveData non ha una cronologia (solo lo stato corrente). Quindi, non dovresti usare LiveData per un'applicazione di chat.
  8. Quando usi LiveData con RxJava non hai bisogno di cose come MediatorLiveData , SwitchMap ecc. Sono strumenti di controllo del flusso e RxJava è meglio in questo senso molte volte.
  9. Guarda LiveData come un detentore di dati e nient'altro. Possiamo anche dire che LiveData è un consumatore consapevole del ciclo di vita.

    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();
         }
    }

5
Guarda LiveData come un detentore di dati e nient'altro. ==> SÌ
Lou Morda,

3
Bell'esempio Hai dimenticato di dichiarare il materiale usa e getta e sarebbe bello eliminarlo onCleared.
Snicolas,

Potresti spiegare come è vissuto sincrono? Per quanto ne so, possiamo inviare l'oggetto Livedata a un altro thread e quindi quel thread può postvalutare quale osservatore può ascoltare nel MainThread.
Hitesh Bisht,

Se leggi di nuovo quello che ho scritto significa che non puoi lavorare su un altro thread solo (SÌ, ho usato "solo" anche lì) usando LiveData come puoi fare usando RxJava
Abhishek Kumar il

Il ciclo di vita non è un grosso fattore di differenziazione per LiveData? Descrivi cosa deve fare la tua pipeline e quali sono i tuoi risultati finali, 2. sottoscrivi il risultato nelle clausole "osservare", e poi 3. la pipeline viene gestita solo se lo stato del tuo ciclo di vita lo consente.
Srg

29

Infatti, LiveData non è uno strumento essenzialmente diverso RxJava, così perché è stato introdotto come componente un'architettura quando RxJavaavrebbe potuto facilmente gestito il ciclo di vita memorizzando tutti gli abbonamenti alla osservabili in un CompositeDispoable oggetto e poi disporle in onDestroy() del Activity o onDestroyView() dei Fragment utilizzando una sola riga di codice?

Ho risposto completamente a questa domanda creando un'app per la ricerca di film una volta usando RxJava e poi usando LiveData qui .

In breve, sì, potrebbe, ma ciò avrebbe prima bisogno di scavalcare i pertinenti metodi del ciclo di vita oltre ad avere le conoscenze di base del ciclo di vita. Questo potrebbe ancora non avere senso per alcuni, ma il fatto è che secondo una delle sessioni Jetpack in Google I / O 2018 molti sviluppatori trovano complesso la gestione del ciclo di vita. Gli errori di crash derivanti dalla mancata gestione della dipendenza dal ciclo di vita potrebbero essere un altro segno che alcuni sviluppatori, anche se ben informati sul ciclo di vita, dimenticano di occuparsene in ogni attività / frammento che usano nella loro app. Nelle app di grandi dimensioni questo potrebbe diventare un problema, nonostante l'effetto negativo che potrebbe avere sulla produttività.

La linea di fondo è che introducendo LiveData, ci si aspetta che un numero maggiore di sviluppatori adotti MVVM senza nemmeno dover comprendere la gestione del ciclo di vita, la perdita di memoria e l'arresto anomalo. Anche se non ho dubbi che LiveDatanon sia confrontabile RxJavain termini di capacità e potenza che offre agli sviluppatori, alla programmazione reattiva ed RxJavaè un concetto e uno strumento difficili da comprendere per molti. D'altra parte, non penso LiveDatache debba essere un sostituto di RxJava- semplicemente non può - ma uno strumento molto semplice per gestire un controverso problema diffuso che molti sviluppatori hanno riscontrato.

** AGGIORNAMENTO ** Ho aggiunto un nuovo articolo qui in cui ho spiegato come l'uso improprio di LiveData può portare a risultati imprevisti. RxJava può venire in soccorso in queste situazioni



2
"perché è stato introdotto quando RxJava avrebbe potuto facilmente gestire il ciclo di vita archiviando tutti gli abbonamenti in un CompositeDispoable e poi disponendoli in onDestroy () dell'Attività" - LiveDataeliminarli in onStoprealtà
arekolek,

@arekolek da parte mia: anche per gestire il CompositeDispoable abbiamo sovrascritto i metodi del ciclo di vita. Ma nei dati Live tutto includerà in un'unica riga di codice. Quindi stiamo salvando almeno 20 righe di codice.
Suresh,

Possiamo definire un baseFragment e definire il metodo usa e getta [] subscriptions () per essere sostituito da tutti i frammenti derivati, chiamare questo metodo in onCreateView e aggiungere il valore restituito in CompositeDisposable, smaltire in onDestroyView, non dimenticare più.
android2013,

Non si tratta solo di smaltire. Usando RxJava, devi disporre su onStop, quindi iscriverti di nuovo su onStart / onResume, gestire le modifiche alla configurazione e fare un sacco di altre cose. Ecco perché ci sono così tanti crash usando RxJava. LiveData gestisce tutto ciò, ma non è flessibile come RxJava.
user932178

24

Come forse saprai nell'ecosistema reattivo, abbiamo un osservabile che emette dati e un osservatore che sottoscrive (ricevi una notifica) di questa emissione osservabile, nulla di strano è il modo in cui funziona il cosiddetto modello di osservatore. Un osservabile "grida" qualcosa, l'Osservatore viene avvisato che un osservabile grida qualcosa in un dato momento.

Pensa a LiveDataun osservabile che ti consente di gestire gli osservatori che si trovano in uno activestato. In altri termini LiveDataè un semplice osservabile ma si occupa anche del ciclo di vita.

Ma vediamo i due casi di codice richiesti:

A) Dati in tempo reale

B) RXJava

A) Questa è un'implementazione di base di LiveData

1) di solito crea un'istanza di LiveData in ViewModel per mantenere il cambiamento di orientamento (puoi avere LiveData di sola lettura o MutableLiveData che è scrivibile, quindi di solito esponi al di fuori della classe LiveData)

2) nel OnCreatemetodo dell'attività principale (non ViewModel) "abbonati" un oggetto Observer (di solito un metodo onChanged)

3) si avvia il metodo osservare per stabilire il collegamento

Prima il ViewModel (possiede la logica aziendale)

class ViewModel : ViewModel() { //Point 1

    var liveData: MutableLiveData<Int> = MutableLiveData()

}

E questo è il MainActivity(più stupido possibile)

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) Questa è l'implementazione di base di RXJava

1) dichiari un osservabile

2) dichiari un osservatore

3) sottoscrivi l'Osservabile con l'Osservatore

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);
       }
    });

In particolare LiveDataviene utilizzato con Lifecyclee spesso con ViewModel(come abbiamo visto) componenti di architettura. Infatti quando LiveDatacombinato con un ViewModel ti permette di essere aggiornato in tempo reale ogni cambiamento in Observer, in modo che gli eventi siano gestiti in tempo reale dove è necessario. Ad uso LiveDataè fortemente consigliato di conoscere il concetto di ciclo di vita e la relativa oggetti LifeCycleOwner / LifeCycle , anche io vi consiglio di dare un'occhiata al Trasformazioni , se si desidera implementare LiveDatain scenari di vita reale. Qui puoi trovare alcuni casi d'uso dal grande commonsware .

Riassumendo sostanzialmenteLiveDataè un modo semplificatoRXJavaed elegante per osservare le modifiche tra più componenti senza creare esplicite regole di dipendenza esplicite tra i componenti, in modo da poter testare molto più facilmente il codice e renderlo molto più leggibile. RXJava, ti permette di fare le cose di LiveData e molto altro. A causa delle funzionalità estese di RXJava, puoi utilizzare LiveData per casi semplici o sfruttare tutta la potenza di RXJava usando i componenti di Android Architecture come ViewModel , ovviamente questo significa cheRXJava può essere molto più complesso, basti pensare che ha invece centinaia di operatori di SwitchMap e Mappa di LiveData (al momento).

RXJava versione 2 è una libreria che ha rivoluzionato il paradigma Object Oriented, aggiungendo un cosiddetto modo funzionale per gestire il flusso del programma.


4

LiveData è un sottoinsieme dei componenti dell'architettura Android sviluppato dal team Android.

Con i dati live e altri componenti dell'architettura, le perdite di memoria e altri problemi simili vengono gestiti dai componenti dell'architettura. Dal momento che è sviluppato dal team Android, è il migliore per Android. Forniscono inoltre aggiornamenti che gestiscono le nuove versioni di Android.

Se desideri utilizzare solo nello sviluppo di app Android, scegli i componenti dell'architettura Android. Altrimenti, se si desidera utilizzare altre app Java, come app Web, app desktop, ecc., Utilizzare RxJava


Ho tentato di chiarire la tua risposta. Se sono in qualche modo in conflitto con il tuo intento originale, sentiti libero di modificarlo. In tal caso, prova a renderlo più chiaro della revisione iniziale. L'ultima parte della tua risposta onestamente non aveva senso.
Zoe,

2

LiveDatacome un detentore di dati e nient'altro. Possiamo anche dire che LiveData è un consumatore consapevole del ciclo di vita.LiveDatasi consiglia vivamente di conoscere il concetto di ciclo di vita e gli oggetti relativi LifeCycleOwner / LifeCycle, ottenere capacità di trasformazione e streaming per la logica aziendale e operazioni consapevoli del ciclo di vita per l'interfaccia utente.

Rx è un potente strumento che consente di risolvere i problemi in un elegante stile dichiarativo. Gestisce opzioni lato business o operazioni di Service Api


0

Il confronto tra LiveData e RxJava sta paragonando le mele alle macedonie.

Confronta LiveData con ContentObserver e stai confrontando le mele con le mele. LiveData è effettivamente un sostituto consapevole del ciclo di vita di ContentObserver.

Confrontare RxJava con AsyncTask o qualsiasi altro strumento di threading sta paragonando le macedonie alle arance, perché RxJava aiuta con molto più del semplice threading.


0
  • LiveData equivale parzialmente a Rx Subject o SharedRxObservable

  • LiveData gestisce il ciclo di vita dell'abbonamento ma l'abbonamento Rx Subject deve essere creato e smaltito manualmente

  • LiveData non ha uno stato di terminazione ma Rx Subject ha OnError e OnCompleted

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.