>

Architecture Components: LiveData y ViewModel #AndroidMeetsKotlin

Francisco Manuel López Jurado     Colaboraciones    08/02/2019


Google está empezando a marcar guías y dando consejos sobre la arquitectura a definir en las aplicaciones que vas a desarrollar o mejorar. Por este motivo, nace el concepto de “Architecture Components”, se trata de todos los componentes, herramientas y útiles que permitirán desarrollar su arquitectura planteada de una forma correcta y marcando un estándar entre todos los desarrolladores. En este post, obtendrás información sobre LiveData y ViewModel, los cuales son los elementos a utilizar entre nuestros Activities / Fragments y nuestro repositorio. Concretamente la arquitectura a desarrollar debe seguir el siguiente diagrama:

Este primer post está encaminado en detallar lo incluído en el recuadro azul. En cuanto al elemento llamado “Repositorio”, sólo veremos que hará la llamada a un servicio pero en posteriores post irás conociendo para qué se usa y hasta dónde llega su competencia dentro de esta arquitectura. Podrás obtener más información en el siguiente enlace.

Antes de nada, debes conocer para qué se usan y cuales son las ventajas de LiveData y ViewModel:

LiveData

En resumidas palabras, se trata de una clase que retiene la información de nuestros objetos y tiene la capacidad de ser observable. Lo más importante, y es lo que le distingue de otros posibles patrones observables, es la capacidad de adaptarse y optimizar el uso de los datos al ciclo de vida de Android. De esta forma, LiveData sólo notificará a los elementos suscritos si éstos están activos.

Éste era uno de los principales problemas del “Presenter” en el MVP, por lo que gracias a este componente, nos quitamos este problema de un plumazo.

Resumiendo sus ventajas:

  • Perfecta sincronización con el ciclo de vida de la UI.
  • Adiós a los MemoryLeaks (se libera cuando debe).
  • Adiós al control manual del ciclo de vida.
  • Datos actualizados en todo momento.
  • No se ven afectados por los cambios de configuración.

Es importante saber que LiveData es una clase abstracta, por lo que cuando quieras publicar datos en él, debes usar la clase MutableLiveData. Ésta tiene dos métodos:

  • setValue(T value). Este método sólo se puede ejecutar si sabemos que estamos en hilo principal, en otro caso, provocará una excepción.
  • postValue(T value). Este método tardará un poco en publicar los datos en nuestro LiveData pero lo hará de manera asíncrona, por lo que no importa desde el hilo que se llame.

Antes de poder empezar a usarlo, debes conocer qué es un ViewModel.

ViewModel

Se trata de una clase que está diseñada para almacenar y administrar datos relacionados con la UI de forma optimizada para el ciclo de vida en Android.

En la práctica, lo usarás para almacenar todos los LiveData que necesitará tu vista (Fragment o Activity), de esta forma cuando los datos se actualicen se notificará automáticamente a la vista y ésta se encargará de pintarlos. El ciclo de vida de los ViewModel está resumido en la siguiente imagen:

Una vez que ya tenemos un poco claro qué son estos componentes y para qué se pueden usar, debes empezar con su implementación.

Puedes encontrar más información en el siguiente enlace.

Definición del escenario

La app que desarrollarás realizará una llamada a un servicio (para que recuerdes cómo se realizan llamadas a servicios puedes ver el siguiente post) para obtener la lista de proyectos almacenados en Github bajo un nombre concreto, este parámetro será el que llamaremos de ahora en adelante “query”.

En la vista tendremos por el momento:

  • Un campo editable.
  • Un botón que al pulsarlo lanzará la búsqueda.

Cuando se reciban los datos del servicio se pintará un toast con el tamaño de la lista.

Creamos el ViewModel con los LiveData necesarios

Debes crear 2 variables públicas y una privada.

  • private githubRepository: GithubRepository. Se trata de la variable encargada de obtener los datos, ya sea de internet, caché o base de datos. Este apartado no lo veremos en este post.
  • errorMessageLiveData = MutableLiveData<String>(). Se trata de un LiveData que informará a la vista cuando haya un error al obtener los datos del repositorio. Nuestra vista debe suscribirse en él para obtener los datos de error.
  • searchReposLiveData = MutableLiveData<List<GithubRepoDomain>>(). Este LiveData proporcionará los datos a la UI. Nuestra vista debe suscribirse en él para obtener el listado de elementos una vez sean cargados.

Tendrá un método que consultará al repositorio los datos y se encargará de notificar a la vista. Este método lo verás en el apartado de “Actualizamos los datos”.

Registramos la UI al ViewModel

Una vez ya tienes creado el ViewModel, tienes que registrar tu vista a sus LiveData para estar informado cuando haya un cambio en ellos. Para ello debes:

  • Crear la variable viewModel como un lateinit.

  • Inicializar el ViewModel haciendo uso de ViewModelProviders.

  • Registrarse como observador en todos los LiveData que necesites.

El código lo puedes encontrar aquí.

Actualizamos los datos

En el Repositorio tendrás la siguiente implementación:

Una vez la llamada haya ido bien o mal, simplemente debes pasar los datos obtenidos de la llamada a la función pasada por parámetros. Estos datos serán obtenidos por el ViewModel y éste se encargará de publicarlos en los LiveData del ViewModel con el método “postValue”. Este método del ViewModel quedaría así:

Además, el código de esta clase lo puedes encontrar aquí y el del proyecto bajo el siguiente enlace.

En resumen, los nuevos componentes mejoran los problemas de ciclos de vida que nos encontrábamos en MVP y aportan una arquitectura más robusta y adaptada a los ciclos de vida de Android. En siguientes post mejorarás la implementación realizada con los métodos de la clase Transformations y avanzarás en la arquitectura MVVM propuesta por Google.


Sobre el autor

Francisco Manuel López Jurado   

Apasionado de la tecnología y todo lo que la rodea. Desarrollador Senior Android e iOS.