¿Cuándo usar RxJava en Android y cuándo usar LiveData de Android Architectural Components?


186

No obtengo la razón para usar RxJava en Android y LiveData de Android Architectural Components. Sería realmente útil si los casos de uso y las diferencias entre ambos se explican junto con un ejemplo de ejemplo en forma de código que explica las diferencias entre ambos.


66
¿Ya encontraste una buena razón? Me pregunto lo mismo ...
IgorGanapolsky

Respuestas:


117

Android LiveData es una variante del patrón de observación original, con la incorporación de transiciones activas / inactivas. Como tal, es muy restrictivo en su alcance.

Usando el ejemplo descrito en Android LiveData , se crea una clase para monitorear los datos de ubicación y registrar y cancelar el registro en función del estado de la aplicación.

RxJava proporciona operadores que están mucho más generalizados. Supongamos que este observable proporcionará datos de ubicación:

Observable<LocationData> locationObservable;

La implementación del observable se puede construir utilizando Observable.create()para mapear las operaciones de devolución de llamada. Cuando el observable se suscribe, la devolución de llamada se registra, y cuando se cancela la suscripción, la devolución de llamada no se registra. La implementación se ve muy similar al código proporcionado en el ejemplo.

Supongamos también que tiene un observable que emite true cuando la aplicación está activa:

Observable<Boolean> isActive;

Entonces puede proporcionar toda la funcionalidad de LiveData de la siguiente manera

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

El switchMap()operador proporcionará la ubicación actual como una secuencia o nada si la aplicación no está activa. Una vez que tenga el liveLocationobservable, hay muchas cosas que puede hacer con los operadores de RxJava. Mi ejemplo favorito es:

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

Eso solo realizará la acción cuando la ubicación haya cambiado, y la ubicación sea interesante. Puede crear operaciones similares que combinen operadores de tiempo para determinar la velocidad. Más importante aún, puede proporcionar un control detallado de si las operaciones suceden en el subproceso principal o en un subproceso en segundo plano o en varios subprocesos, utilizando operadores RxJava.

El punto de RxJava es que combina el control y el tiempo en un solo universo, utilizando operaciones proporcionadas por la biblioteca, o incluso operaciones personalizadas que usted proporciona.

LiveData se dirige solo a una pequeña parte de ese universo, el equivalente a construir el liveLocation.


2
Gracias, los documentos de LiveData ya no parecen hacer referencia a una muestra de ubicación. Aquí hay más puntos interesantes (con una muestra de ubicación): androidkt.com/livedata
Daniel Wilson

55
@DanielWilson el enlace ya no está disponible.
Tura

Amigo, no recuerdo qué wtf estaba en ese enlace: DI me gusta el código de muestra de Mark Allison para datos en 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. Pero no es consciente el ciclo de vida de LiveData. Si tuviéramos que usar Rx, ¿no tendríamos que manejar los cambios del ciclo de vida?
Sparker0i

@ Sparker0i consiguió el punto aquí. RxJava no conoce el ciclo de vida. Tenemos que manejarlo manualmente. donde, como en LiveData, ya se ocupa del ciclo de vida.
Aks4125

119

En cuanto a la pregunta original, tanto RxJava como LiveData se complementan muy bien.

LiveDatabrilla en la capa ViewModel, con su estrecha integración con los ciclos de vida y Android ViewModel. RxJavaproporciona más capacidades en transformaciones (como lo menciona @Bob Dalgleish).

Actualmente, estamos usando RxJavafuentes de datos y capas de repositorio, y se transforma en LiveData(usando LiveDataReactiveStreams) en ViewModels (antes de exponer datos a actividades / fragmentos), bastante contento con este enfoque.


8
Si lo entendimos correctamente, entonces LiveData solo es útil para implementaciones específicas de la interfaz de usuario de Android. Si solo estamos creando una aplicación genérica con Clean Architecture y compartimos esta arquitectura con otras plataformas, ¿entonces RxJava es mejor que LiveData?
IgorGanapolsky

@IgorGanapolsky, ¿qué idioma / marcos utiliza para la aplicación genérica?
kzotin

API independientes de Android y Clean Arch escritos en Java / Kotlin.
IgorGanapolsky

1
¿Puedes sugerir algún ejemplo de funcionamiento de LiveDataReactiveStreams en tu respuesta?
Pawan

2
@kzotin no necesitas eso observeOn, lo LiveDataReactiveStreamshace de todos modos llamando LiveData.postValue(). Y no hay garantía de que su subscribeOnvoluntad tenga ningún efecto en general.
arekolek

77

Hay muchas diferencias entre LiveData y RxJava:

  1. LiveData no es un STREAM mientras que en RxJava todo (literalmente todo) es un STREAM .
  2. LiveData es una clase de titular de datos observable. A diferencia de un observable regular, LiveData es consciente del ciclo de vida, lo que significa que respeta el ciclo de vida de otros componentes de la aplicación, como actividades, fragmentos o servicios. Esta conciencia garantiza que LiveData solo actualiza los observadores de componentes de la aplicación que se encuentran en un estado de ciclo de vida activo.
  3. LiveData es sincrónico , por lo que no puede ejecutar un fragmento de código (llamada de red, manipulación de base de datos, etc.) de forma asincrónica utilizando solo LiveData como lo hace con RxJava.
  4. Lo mejor que puede hacer para aprovechar al máximo este dúo es usar RxJava para su lógica de negocios (llamada de red, manipulación de datos, etc., cualquier cosa que ocurra dentro y más allá del repositorio ) y usar LiveData para su capa de presentación. Con esto, obtiene capacidades de transformación y transmisión para su lógica de negocio y operación consciente del ciclo de vida para su interfaz de usuario.
  5. LiveData y RxJava se complementan si se usan juntos. Lo que quiero decir es que haga todo con RxJava y, al final, cuando desee actualizar la interfaz de usuario, haga algo como el código que figura a continuación para cambiar su Observable a LiveData. Entonces, su Vista (UI) observa el LiveData en ViewModel donde su LiveData no es más que MutableLiveData no mutable (o MutableLiveData es LiveData mutable).
  6. Entonces la pregunta aquí es, ¿por qué deberías usar LiveData en primer lugar? Como puede ver a continuación en el código, almacena su respuesta de RxJava a MutableLiveData (o LiveData) y su LiveData es consciente del ciclo de vida, por lo que, de alguna manera, sus datos lo son. Ahora, imagine la posibilidad de que sus datos sepan cuándo y cuándo no actualizar la IU.
  7. LiveData no tiene un historial (solo el estado actual). Por lo tanto, no debe usar LiveData para una aplicación de chat.
  8. Cuando usa LiveData con RxJava, no necesita cosas como MediatorLiveData , SwitchMap , etc. Son herramientas de control de flujo y RxJava es mejor en muchas ocasiones.
  9. Vea LiveData como un titular de datos y nada más. También podemos decir que LiveData es un consumidor consciente del ciclo de vida.

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

55
Vea LiveData como un titular de datos y nada más. ==> SÍ
Lou Morda

3
Buen ejemplo Olvidó declarar el desechable y sería bueno eliminarlo onCleared.
Snicolas

¿Podría explicar cómo livedata es sincrónico? Hasta donde yo sé, podemos enviar un objeto Livedata a otro hilo y luego ese hilo puede tener un valor posterior que el observador puede escuchar en el hilo principal.
Hitesh Bisht

Si vuelve a leer lo que escribí, significa que no puede trabajar en otro hilo solo (SÍ, usé "solo" incluso allí) usando LiveData como puede hacerlo usando RxJava
Abhishek Kumar

¿No es el ciclo de vida un gran diferenciador para LiveData? Usted 1. describe lo que su tubería necesita hacer y cuáles son sus resultados finales, 2. se suscribe al resultado en cláusulas de "observación", Y luego 3. la tubería solo se opera si su estado de ciclo de vida lo permite.
Srg

29

De hecho, LiveData no es una herramienta esencialmente diferente RxJava, entonces, ¿por qué se introdujo como un componente de arquitectura cuando RxJavapodría haber gestionado fácilmente el ciclo de vida almacenando todas las suscripciones en CompositeDispoable objetos observables en un objeto y luego eliminándolos onDestroy() del Activity o onDestroyView() del Fragment usando solo uno? línea de código?

He respondido completamente a esta pregunta construyendo una aplicación de búsqueda de películas una vez usando RxJava y luego usando LiveData aquí .

Pero en resumen, sí, podría, pero eso necesitaría anular primero los métodos relevantes del ciclo de vida además de tener el conocimiento básico del ciclo de vida. Es posible que esto todavía no tenga sentido para algunos, pero el hecho es que, según una de las sesiones de Jetpack en Google I / O 2018, muchos desarrolladores encuentran complejo el manejo del ciclo de vida. Los errores de bloqueo que surgen de no manejar la dependencia del ciclo de vida podrían ser otra señal de que algunos desarrolladores, incluso si conocen el ciclo de vida, se olvidan de ocuparse de eso en cada Actividad / Fragmento que usan en su aplicación. En aplicaciones grandes, esto podría convertirse en un problema, a pesar del efecto negativo que podría tener sobre la productividad.

La conclusión es que al presentar LiveData, se espera que un mayor número de desarrolladores adopten MVVM sin siquiera tener que comprender la gestión del ciclo de vida, la pérdida de memoria y el bloqueo. Aunque no tengo dudas de que LiveDatano es comparable RxJavaen términos de capacidades y el poder que brinda a los desarrolladores, la programación reactiva y RxJavaes un concepto y una herramienta difíciles de entender para muchos. Por otro lado, no creo que LiveDataesté destinado a ser un reemplazo de RxJava–simplemente no puede–, sino una herramienta muy simple para manejar un problema polémico generalizado experimentado por muchos desarrolladores.

** ACTUALIZACIÓN ** He agregado un nuevo artículo aquí donde he explicado cómo el mal uso de LiveData puede conducir a resultados inesperados. RxJava puede venir a rescatar en estas situaciones



2
"¿por qué fue introducido cuando RxJava podría haber conseguido fácilmente el ciclo de vida mediante el almacenamiento de todas las suscripciones en un CompositeDispoable y luego disponiéndolos en OnDestroy () de la Actividad" - LiveDatadispondría en onStoprealidad
arekolek

@arekolek, según tengo entendido: incluso para manejar el CompositeDispoable, hemos sobrescrito los métodos del ciclo de vida. Pero en los datos en vivo todos se incluirán en una sola línea de código. Entonces estamos ahorrando un mínimo de 20 líneas de código.
Suresh

Podemos definir un baseFragment y definir el método Disposable [] suscriptions () para que sea anulado por todos los fragmentos derivados, llame a este método en onCreateView y agregue el valor de retorno en CompositeDisposable, elimínelo en onDestroyView, sin olvidar más.
android2013

No se trata solo de deshacerse. Con RxJava, debe disponer en onStop, luego suscribirse nuevamente en onStart / onResume, manejar los cambios de configuración y hacer un montón de otras cosas. Es por eso que hay tantos bloqueos usando RxJava. LiveData maneja todo eso, pero no es tan flexible como RxJava.
user932178

24

Como puede saber en el ecosistema reactivo, tenemos un Observable que emite datos y un Observador que se suscribe (recibe una notificación) de esta emisión Observable, nada extraño es cómo funciona el llamado Patrón de Observador. Un Observable "grita" algo, el Observador recibe una notificación de que Observable grita algo en un momento dado.

Piense LiveDatacomo un Observable que le permite administrar los Observadores que se encuentran en un activeestado. En otros términos, LiveDataes un Observable simple pero también se encarga del ciclo de vida.

Pero veamos los dos casos de código que solicita:

A) Datos en vivo

B) RXJava

A) Esta es una implementación básica de LiveData

1) generalmente crea una instancia de LiveData en ViewModel para mantener el cambio de orientación (puede tener LiveData que es de solo lectura o MutableLiveData que se puede escribir, por lo que generalmente se expone fuera de la clase LiveData)

2) en el OnCreatemétodo de la Actividad principal (no en ViewModel) "suscribe" un objeto Observador (generalmente un método onChanged)

3) inicia el método observar para establecer el enlace

Primero el ViewModel(posee la lógica de negocios)

class ViewModel : ViewModel() { //Point 1

    var liveData: MutableLiveData<Int> = MutableLiveData()

}

Y este es el MainActivity(lo más tonto posible)

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) Esta es la implementación básica de RXJava

1) declaras un Observable

2) declaras un observador

3) suscribes el Observable con el Observador

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 particular, LiveDatase utiliza con Lifecycley a menudo con ViewModel(como hemos visto) componentes de arquitectura. De hecho, cuando LiveDatase combina con un ViewModel le permite mantenerse actualizado en tiempo real de cada cambio en el Observador, para que los eventos se gestionen en tiempo real donde sea necesario. Para usarlo, LiveDatase recomienda conocer el concepto de ciclo de vida y los objetos relativos LifeCycleOwner / LifeCycle , también le sugiero que eche un vistazo a las Transformaciones , si desea implementar LiveDataen escenarios de la vida real. Aquí puede encontrar algunos casos de uso del gran software común .

Para terminar , básicamente,LiveDataes una simplificaciónRXJava, una manera elegante para observar los cambios a través de múltiples componentes sin necesidad de crear las denominadas reglas explícitas de dependencia entre los componentes, por lo que se puede probar mucho más fácil el código y hacer que sea mucho más fácil de leer. RXJava, te permite hacer cosas de LiveData y mucho más. Debido a las funcionalidades extendidas de RXJava, puede usar LiveData para casos simples o explotar todo el poder de RXJava para seguir usando los componentes de Android Architecture como ViewModel , por supuesto, esto significa queRXJavapuede ser mucho más complejo, solo piense que tiene cientos de operadores en su lugar de SwitchMap y Map of LiveData (por el momento).

RXJava versión 2 es una biblioteca que revolucionó el paradigma orientado a objetos, agregando una forma funcional llamada para administrar el flujo del programa.


4

LiveData es un subconjunto de los componentes de la arquitectura de Android desarrollado por el equipo de Android.

Con los datos en vivo y otros componentes de la arquitectura, los componentes de la arquitectura manejan las pérdidas de memoria y otros problemas similares. Dado que está desarrollado por el equipo de Android, es el mejor para Android. También proporcionan actualizaciones que manejan nuevas versiones de Android.

Si solo desea usar en el desarrollo de aplicaciones de Android, vaya a los componentes de arquitectura de Android. De lo contrario, si desea usar otra aplicación Java, como aplicaciones web, aplicaciones de escritorio, etc., use RxJava


Intenté aclarar tu respuesta. Si de alguna manera he entrado en conflicto con tu intención original, no dudes en editar. Si lo hace, intente hacerlo más claro que la revisión inicial. La última parte de su respuesta honestamente no tenía sentido.
Zoe

2

LiveDatacomo titular de datos y nada más. También podemos decir que LiveData es un consumidor consciente del ciclo de vida. LiveDataSe recomienda encarecidamente conocer el concepto de ciclo de vida y los objetos relativos LifeCycleOwner / LifeCycle, obtendrá capacidades de transformación y transmisión para su lógica de negocio y operación consciente del ciclo de vida para su IU.

Rx es una herramienta poderosa que permite resolver problemas en un elegante estilo declarativo. Maneja las opciones del lado comercial o las operaciones de Service Api


0

Comparar LiveData con RxJava es comparar manzanas con ensaladas de frutas.

Compare LiveData con ContentObserver y está comparando manzanas con manzanas. LiveData efectivamente es un reemplazo consciente del ciclo de vida para ContentObserver.

Comparar RxJava con AsyncTask o cualquier otra herramienta de enhebrado es comparar ensaladas de frutas con naranjas, porque RxJava ayuda con más que solo enhebrar.


0
  • LiveData es parcialmente igual a Rx Subject o SharedRxObservable

  • LiveData gestiona el ciclo de vida de la suscripción, pero la suscripción de Rx Subject debe crearse y eliminarse manualmente

  • LiveData no tiene estado de terminación pero Rx Subject tiene OnError y OnCompleted

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.