Advertisement
  1. Code
  2. Android SDK

Componentes de la arquitectura de Android: LiveData

by
Read Time:9 minsLanguages:
This post is part of a series called Android Architecture Components.
Android Architecture Components: Lifecycle and LiveModel
Android Architecture Components: the Room Persistence Library

Spanish (Español) translation by Januar (you can also view the original English article)

Ya hemos cubierto mucho terreno en nuestra serie de Componentes de Arquitectura de Android. Comenzamos hablando de la idea detrás de la nueva arquitectura y observando los componentes clave presentados en Google I / O. En la segunda publicación, comenzamos nuestra exploración profunda de los componentes principales del paquete, observando de cerca los componentes de Ciclo de vida y LiveModel. En esta publicación, continuaremos explorando los Componentes de Arquitectura, esta vez analizando el increíble componente LiveData.

Supongo que está familiarizado con los conceptos y componentes cubiertos en los últimos tutoriales, como Lifecycle, LifecycleOwner y LifecycleObserver. Si no es así, eche un vistazo a la primera publicación de esta serie, donde discuto la idea general detrás de la nueva arquitectura de Android y sus componentes.

Continuaremos construyendo sobre la aplicación de ejemplo que comenzamos en la última parte de esta serie. Puedes encontrarlo en el tutorial del repositorio de GitHub.

1. El componente LiveData

LiveData es un titular de los datos. Es capaz de ser observado, puede contener cualquier tipo de datos, y además de eso, es consciente del ciclo de vida. En términos prácticos, LiveData se puede configurar para enviar solo actualizaciones de datos cuando su observador está activo. Gracias a su reconocimiento del ciclo de vida, cuando el LifecycleOwner lo observa, el componente LiveData enviará actualizaciones solo cuando el Ciclo de vida del observador todavía esté activo, y eliminará la relación observada una vez que se destruya el Ciclo de vida del observador.

El componente LiveData tiene muchas características interesantes:

  • evita las pérdidas de memoria cuando el observador está vinculado a un ciclo de vida
  • Previene choques debido a actividades detenidas.
  • los datos están siempre actualizados
  • Maneja los cambios de configuración sin problemas.
  • hace posible compartir recursos
  • maneja automáticamente el ciclo de vida

2. Observando LiveData

Un componente LiveData envía actualizaciones de datos solo cuando su observador está "activo". Cuando es observado por un LifecycleOwner, el componente LiveData considera que el observador está activo solo mientras su Ciclo de vida está en los estados INICIADOS o REANUDADOS, de lo contrario considerará al observador como inactivo. Durante el estado inactivo del observador, LiveData detendrá el flujo de actualización de datos, hasta que su observador se vuelva a activar. Si el observador es destruido, LiveData eliminará su referencia al observador.

LiveData update flowLiveData update flowLiveData update flow

Para lograr este comportamiento, LiveData crea una estrecha relación con el ciclo de vida del observador cuando es observado por un LifecycleOwner. Esta capacidad hace que sea más fácil evitar las fugas de memoria al observar LiveData. Sin embargo, si se llama al proceso de observación sin un LifecycleOwner, el componente LiveData no reaccionará al estado del ciclo de vida, y el estado del observador debe manejarse manualmente.

Para observar un LiveData, llame a observe (LifecycleOwner, Observer ) u observeForever (Observer ).

  • observe (LifecycleOwner, Observer ): esta es la forma estándar de observar un LiveData. Vincula al observador con un ciclo de vida, cambiando el estado activo e inactivo de LiveData según el estado actual de LifecycleOwner
  • observeForever (Observer ): este método no utiliza un LifecycleOwner, por lo que LiveData no podrá responder a los eventos de Lifecycle. Al usar este método, es muy importante llamar a removeObserver (Observer ), de lo contrario, es posible que el observador no sea recolectado como basura, lo que provoca una pérdida de memoria.

3. Implementando LiveData

El tipo genérico en la clase LiveData define el tipo de datos que se retendrán. Por ejemplo, LiveData contiene datos de ubicación. O LiveData tiene una cadena.

Hay dos métodos principales que deben considerarse en la implementación del componente: onActive () y onInactive (). Ambos métodos reaccionan al estado del observador.

Ejemplo de implementación

En nuestro proyecto de ejemplo, usamos muchos objetos LiveData, pero solo implementamos uno: LocationLiveData. La clase trata con la ubicación de GPS, pasando la posición actual solo para un observador activo. Observe que la clase actualiza su valor en el método onLocationChanged, y pasa al observador activo actual los datos de ubicación actualizados.

4. La clase de ayuda MutableLiveData

MutableLiveData es una clase auxiliar que amplía LiveData y expone los métodos postValue y setValue. Aparte de eso, se comporta exactamente igual que su padre. Para usarlo, defina el tipo de datos que contiene, como MutableLiveData para mantener una cadena y crear una nueva instancia.

Para enviar actualizaciones a un observador, llame a postValue o setValue. El comportamiento de estos métodos es bastante similar; sin embargo, setValue establecerá directamente un nuevo valor y solo se puede llamar desde el hilo principal, mientras que postValue crea una nueva tarea en el hilo principal para establecer el nuevo valor y se puede llamar desde un hilo de fondo.

Es importante tener en cuenta que, dado que el método postValue crea una nueva tarea y publica en el hilo principal, será más lento que las llamadas directas a setValue.

5. Transformaciones de LiveData

Eventualmente, deberá cambiar un LiveData y propagar su nuevo valor a su observador. O tal vez necesite crear una reacción en cadena entre dos objetos LiveData, haciendo que uno reaccione a los cambios en otro. Para lidiar con ambas situaciones, puedes usar la clase Transformaciones.

Transformaciones de mapas

Transformations.map aplica una función en una instancia de LiveData y envía el resultado a sus observadores, dándole la oportunidad de manipular el valor de los datos.

Transformationsmap flowTransformationsmap flowTransformationsmap flow

Es muy fácil implementar Transformations.map. Todo lo que debe hacer es proporcionar un LiveData para ser observado y una función para ser llamada cuando el LiveData observado cambie, recordando que la función debe devolver el nuevo valor del LiveData transformado.

Supongamos que tiene un LiveData que debe llamar a una API cuando cambia un valor de cadena, como un campo de búsqueda.

Transformaciones SwitchMap

Transformations.switchMap es bastante similar a Transformations.map, pero como resultado debe devolver un objeto LiveData. Es un poco más difícil de usar, pero te permite construir reacciones en cadena potentes.

En nuestro proyecto, utilizamos Transformations.switchMap para crear una reacción entre LocationLiveData y ApiResponse .

  1. Nuestro Transformation.switchMap observa los cambios de LocationLiveData.
  2. El valor actualizado de LocationLiveData se usa para llamar a MainRepository para obtener el clima para la ubicación especificada.
  3. El repositorio llama al OpenWeatherService que produce un LiveData > como resultado.
  4. Luego, el LiveData devuelto es observado por un MediatorLiveData, que es responsable de modificar el valor recibido y actualizar el clima exhibido en la capa de vista.

Sin embargo, tenga cuidado con las operaciones que consumen mucho tiempo en sus transformaciones de LiveData. En el código anterior, ambos métodos de transformación se ejecutan en el hilo principal.

6. El MediatorLiveData

MediatorLiveData es un tipo más avanzado de LiveData. Tiene capacidades muy similares a las de la clase Transformaciones: puede reaccionar a otros objetos LiveData, llamando a una función cuando los datos observados cambian. Sin embargo, tiene muchas ventajas en comparación con Transformations, ya que no necesita ejecutarse en el hilo principal y puede observar múltiples LiveDatas a la vez.

Para observar un LiveData, llame a addSource (LiveData , Observer ), haciendo que el observador reaccione al método onChanged desde el LiveData dado. Para detener la observación, llame a removeSource (LiveData ).

En nuestro proyecto, los datos observados por la capa de vista que contiene el clima para exhibir es un MediatorLiveData. El componente observa otros dos objetos LiveData: weatherByLocationResponse, que recibe actualizaciones meteorológicas por ubicación, y weatherByCityResponse, que recibe actualizaciones meteorológicas por nombre de ciudad. Cada vez que estos objetos se actualicen, weatherByCityResponse actualizará la capa de vista con el clima actual solicitado.

En MainViewModel, observamos LiveData y proporcionamos el objeto meteorológico para ver.

En MainActivity, se observa el clima y se muestra su resultado al usuario.

El MediatorLiveData también se usó como la base de un objeto que maneja las llamadas a la API de OpenWeatherMap. Eche un vistazo a esta implementación; Es más avanzado que los anteriores, y realmente vale la pena estudiarlo. Si está interesado, eche un vistazo a OpenWeatherService, prestando especial atención a la clase Mediator .

7. Conclusión

Estamos casi al final de nuestra exploración de los Componentes de Arquitectura de Android. A estas alturas, deberías entender lo suficiente como para crear algunas aplicaciones poderosas. En la próxima publicación, exploraremos Room, un ORM que contiene SQLite y puede producir resultados de LiveData. El componente de sala encaja perfectamente en esta arquitectura, y es la pieza final del rompecabezas.

¡Te veo pronto! Y mientras tanto, echa un vistazo a algunas de nuestras otras publicaciones sobre el desarrollo de aplicaciones para Android.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.