¿Cuándo usar RxJava en Android y cuándo usar LiveData desde componentes arquitectónicos de Android?
No entiendo la razón para usar RxJava en Android y LiveData de los componentes arquitectónicos de Android. Sería realmente útil si los casos de uso y las diferencias entre ambos se explicaran junto con un ejemplo de muestra en forma de código que explique las diferencias entre ambos.
Respecto a la pregunta original, tanto RxJava como LiveData se complementan muy bien.
LiveData
brilla en la capa ViewModel, con su estrecha integración con los ciclos de vida de Android y ViewModel
. RxJava
proporciona más capacidades en transformaciones (como lo menciona @Bob Dalgleish).
Actualmente, lo estamos usando RxJava
en capas de fuente y repositorio de datos, y se transforma LiveData
(usando LiveDataReactiveStreams
) en ViewModels (antes de exponer los datos a actividades/fragmentos); estoy muy contento con este enfoque.
Android LiveData es una variante del patrón de observador original, con la adición de transiciones activo/inactivo. Como tal, su alcance es muy restrictivo.
Usando el ejemplo descrito en Android LiveData , se crea una clase para monitorear los datos de ubicación y registrar y cancelar el registro según el estado de la aplicación.
RxJava proporciona operadores 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 está suscrito, la devolución de llamada se registra y cuando se da de baja, la devolución de llamada se da de baja. La implementación es 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;
Luego 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 liveLocation
observable, hay muchas cosas que puede hacer con él utilizando los operadores 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 cambie 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 ocurren en el subproceso principal, en un subproceso en segundo plano o en varios subprocesos, utilizando operadores RxJava.
El objetivo de RxJava es que combina control y temporización en un único universo, utilizando operaciones proporcionadas por la biblioteca o incluso operaciones personalizadas que usted proporcione.
LiveData aborda solo una pequeña parte de ese universo, el equivalente a construir el liveLocation
.
Existen muchas diferencias entre LiveData y RxJava:
- LiveData no es un STREAM mientras que en RxJava todo (literalmente todo) es un STREAM .
- LiveData es una clase de titular de datos observables. A diferencia de un observable normal, LiveData tiene en cuenta el ciclo de vida, lo que significa que respeta el ciclo de vida de otros componentes de la aplicación, como actividades, fragmentos o servicios. Este conocimiento garantiza que LiveData solo actualice los observadores de componentes de la aplicación que se encuentran en un estado de ciclo de vida activo.
- LiveData es sincrónico , por lo que no puede ejecutar una porción de código (llamada de red, manipulación de bases de datos, etc.) de forma asincrónica usando solo LiveData como lo hace con RxJava.
- Lo mejor que puede hacer para aprovechar al máximo este dúo es usar RxJava para su lógica de negocios (llamadas de red, manipulación de datos, etc., cualquier cosa que suceda dentro y fuera del Repositorio ) y usar LiveData para su capa de presentación. De esta manera, obtiene capacidades de transformación y transmisión para su lógica empresarial y una operación consciente del ciclo de vida de su interfaz de usuario.
- 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 se proporciona a continuación para cambiar su Observable a LiveData. Entonces, su Vista (UI) observa LiveData en ViewModel donde su LiveData no es más que MutableLiveData no mutable (o MutableLiveData es LiveData mutable).
- 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 en MutableLiveData (o LiveData) y su LiveData tiene en cuenta el ciclo de vida, por lo que, en cierto modo, sus datos tienen en cuenta el ciclo de vida. Ahora, imagine la posibilidad de que sus propios datos sepan cuándo y cuándo no actualizar la interfaz de usuario.
- LiveData no tiene historial (solo el estado actual). Por lo tanto, no deberías utilizar LiveData para una aplicación de chat.
- Cuando usas LiveData con RxJava no necesitas cosas como MediatorLiveData , SwitchMap , etc. Son herramientas de control de transmisión y RxJava es mucho mejor en eso.
- 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();
}
}