Está en la página 1de 1

Descripción general Plataforma

Guías Android Studio Ejemplos


Referencia Google PlayDiseño Jetpack
y calidad Documentos Más ' * Buscar Language Acceder
'
Guía de arquitectura de apps

' Componentes de la arquitectura En esta página


( Filtrar
' Bibliotecas de capas de IU Cómo implementar
un ViewModel
' '

Vinculación de vista
El ciclo de vida de
Biblioteca de vinculación de un ViewModel
datos
Cómo compartir
' Componentes optimizados datos entre
para ciclos de vida
Desarrolladores de Android # Documentos # Guías ¿Te resultó útil?
fragmentos

Cómo controlar ciclos de Cómo reemplazar

Descripción general de ViewModel   


cargadores con
vida
ViewModel
ViewModel
Cómo usar
LiveData Parte de Android Jetpack $ corrutinas con
ViewModel
Cómo guardar estados de
Más información
la IU Se diseñó la clase ViewModel a Tn de almacenar y administrar datos relacionados con la IU de manera optimizada para
los ciclos de vida. La clase ViewModel permite que se conserven los datos luego de cambios de conTguración, como Recursos
Módulo de estado adicionales
las rotaciones de pantallas.
guardado para ViewModel
Ejemplos
Cómo usar las corrutinas
de Kotlin con componentes Codelabs
optimizados para ciclos de ! Nota: Si quieres importar ViewModel a tu proyecto de Android, consulta las instrucciones para declarar dependencias en las
Blogs
vida notas de la versión de Lifecycle.
Videos
'

Biblioteca de Paging
'

Bibliotecas de capas de datos El framework de Android administra los ciclos de vida de los controladores de IU, como las actividades y los
fragmentos. El marco de trabajo podría decidir destruir o recrear un controlador de IU como respuesta a acciones del
' ' '

Puntos de entrada de la app


usuario o eventos del dispositivo determinados que están completamente fuera de tu control.
Navegación en la app

Inserción de dependencias Si el sistema destruye o recrea un controlador de IU, se perderán todos los datos relacionados con la IU que almacenes
en el controlador. Por ejemplo, tu app podría incluir una lista de usuarios en una de sus actividades. Cuando se recrea la
actividad para un cambio de conTguración, la actividad nueva tiene que volver a recuperar la lista de usuarios. En el caso
de los datos simples, la actividad puede usar el método onSaveInstanceState() y restablecer sus datos a partir del
paquete en onCreate() , aunque este enfoque solo es apto para pequeñas cantidades de datos que se pueden
serializar y deserializar, no para cantidades de datos posiblemente grandes, como una lista de usuarios o mapas de bits.
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '

Otro problema es que los controladores de IU frecuentemente necesitan hacer llamadas asíncronas que podrían tardar
en devolverse. El controlador de IU necesita administrar estas llamadas y garantizar que el sistema las borre después de
su destrucción para evitar potenciales pérdidas de memoria. Esta administración requiere mucho mantenimiento y, en
los casos en que se recrea el objeto para un cambio de conTguración, es una pérdida de recursos, ya que el objeto
quizás deba volver a emitir llamadas que ya hizo.

Los controladores de IU, como las actividades y los fragmentos, tienen como objetivo principal mostrar datos de IU,
reaccionar a las acciones de los usuarios o administrar la comunicación del sistema operativo, como las solicitudes de
permisos. Si se establece que los controladores de IU también sean responsables de cargar datos de una red o base de
datos, la clase estará sobrecargada. Asignar demasiadas responsabilidades a los controladores de IU puede provocar
que una sola clase trate de administrar todo el trabajo de una app por su cuenta, en lugar de delegar el trabajo a otras
clases. Si asignas demasiadas responsabilidades a los controladores de IU de este modo, la prueba también se diTculta
considerablemente.

Es más fácil y eTciente separar la propiedad de los datos de visualización de la lógica del controlador de IU.

Cómo implementar un ViewModel


Los componentes de arquitectura proporcionan una clase de ayuda de ViewModel para el controlador de IU que es
responsable de preparar los datos de la IU. Durante los cambios de conTguración, se retienen automáticamente los
objetos ViewModel , de manera que los datos que contienen estén disponibles de inmediato para la siguiente instancia
de actividad o fragmento. Por ejemplo, si necesitas mostrar una lista de usuarios en tu app, asegúrate de asignar la
responsabilidad de adquirir y mantener la lista de usuarios a un ViewModel , en lugar de una actividad o un fragmento,
como se muestra en el siguiente código de muestra:

Kotlin Java

%&
public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<User>>();
            loadUsers();
        }
' ' '

        return users;
    }

    private void loadUsers() {


        // Do an asynchronous operation to fetch users.
    }
}
' '

Luego, puedes acceder a la lista desde una actividad de la siguiente manera:


' ' ' ' ' ' '

Kotlin Java

public class MyActivity extends AppCompatActivity {


    public void onCreate(Bundle savedInstanceState) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = new ViewModelProvider(this).get(MyViewModel.class);


        model.getUsers().observe(this, users -> {
            // update UI
        });
'

    }
}

Si se vuelve a crear la actividad, recibe la misma instancia de MyViewModel que creó la primera actividad. Cuando
Tnaliza la actividad del propietario, el framework llama al método onCleared() de los objetos ViewModel para que
borre los recursos.

" Precaución: Un ViewModel nunca debe hacer referencia a una vista, a un Lifecycle o a cualquier clase que pueda hacer
referencia al contexto de la actividad.

Los objetos ViewModel están diseñados para sobrevivir a instancias especíTcas de vistas o LifecycleOwners . Este
diseño también te permite escribir pruebas para abarcar un ViewModel con mayor facilidad, ya que no sabe acerca de
los objetos de vista y Lifecycle . Los objetos ViewModel pueden contener LifecycleObservers , como objetos
LiveData . Sin embargo, los objetos ViewModel no deben observar cambios en los elementos observables
optimizados para ciclos de vida, como los objetos LiveData . Si el ViewModel necesita el contexto de Application ,
por ejemplo, para buscar un servicio del sistema, puede extender la clase AndroidViewModel y hacer que un
constructor reciba la Application , ya que la clase Application extiende Context .

El ciclo de vida de un ViewModel


El alcance de los objetos ViewModel se determina según el Lifecycle que se pasa al ViewModelProvider cuando
se recibe el ViewModel . El ViewModel permanece en la memoria hasta que el Lifecycle que determina su alcance
desaparece de forma permanente. En el caso de una actividad, cuando termina; en el caso de un fragmento, cuando se
desconecta.

La Tgura 1 muestra los estados del ciclo de vida de una actividad a medida que atraviesa una rotación y hasta que
termina. La ilustración también muestra el ciclo de vida del ViewModel junto al de la actividad asociada. Este diagrama
en particular muestra los estados de una actividad. Los mismos estados básicos se aplican al ciclo de vida de un
fragmento.

Por lo general, solicitas un ViewModel la primera vez que el sistema llama al método onCreate() del objeto de una
actividad. El sistema puede llamar a onCreate() varias veces durante la vida de una actividad, como cuando rota la
pantalla de un dispositivo. El ViewModel existe desde la primera vez que solicitas un ViewModel hasta que Tnaliza la
actividad y se destruye.

Cómo compartir los datos entre fragmentos


Es muy común que dos o más fragmentos en una actividad necesiten comunicarse entre sí. Imagina un caso común de
fragmentos de vista dividida ( list-detail ), en el que tienes un fragmento donde el usuario selecciona un elemento de
una lista y otro fragmento que muestra el contenido del elemento seleccionado. Este caso nunca es banal, ya que
ambos fragmentos necesitan deTnir una parte de la descripción de la interfaz y la actividad del propietario debe
vincularlos. Además, los dos fragmentos deben manejar la situación en la que el otro fragmento todavía no se haya
creado o no esté visible.

Se puede abordar este punto problemático común usando objetos ViewModel . Esos fragmentos pueden compartir un
ViewModel mediante su alcance de actividad para administrar esta comunicación, como se indica en el siguiente
código de muestra:

Kotlin Java

public class SharedViewModel extends ViewModel {


    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {


        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {


        return selected;
    }
}

public class ListFragment extends Fragment {


    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {


        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {


        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), item -> {
           // Update the UI.
        });
    }
}

Ten en cuenta que ambos fragmentos recuperan la actividad que los contiene. De esa manera, cuando cada fragmento
obtiene el ViewModelProvider , reciben la misma instancia de SharedViewModel , cuyo alcance está determinado por
esta actividad.

Este enfoque ofrece las siguientes ventajas:

La actividad no necesita hacer nada ni saber sobre esta comunicación.

Los fragmentos no necesitan saber acerca del otro, excepto por el contrato de SharedViewModel . Si uno de los
fragmentos desaparece, el otro sigue funcionando como de costumbre.

Cada fragmento tiene su propio ciclo de vida y no se ve afectado por el ciclo de vida del otro. Si un fragmento
reemplaza al otro, la IU continúa funcionando sin problemas.

Cómo reemplazar cargadores con ViewModel


Con frecuencia, se usan las clases de cargador como CursorLoader para mantener los datos en la IU de una app
sincronizados con una base de datos. Puedes usar ViewModel , con algunas otras clases, para reemplazar el cargador.
Usar un ViewModel te permite separar el controlador de IU de la operación de carga de datos. De esa forma, tienes
menos referencias pesadas entre clases.

En un enfoque común con respecto al uso de cargadores, una app podría usar un CursorLoader para observar el
contenido de una base de datos. Cuando un valor en la base de datos cambia, el cargador activa automáticamente una
nueva carga de los datos y actualiza la IU.

Figura 2: carga de datos con cargadores

ViewModel funciona con Room y LiveData para reemplazar el cargador. El ViewModel garantiza que los datos
sobrevivan al cambio de conTguración del dispositivo. Room informa sobre tu LiveData cuando cambia la base de
datos, y LiveData, a su vez, actualiza la IU con los datos revisados.

Figura 3: carga de datos con ViewModel

Cómo usar corrutinas con ViewModel


ViewModel incluye compatibilidad con corrutinas de Kotlin. Para obtener más información, consulta Cómo usar
corrutinas de Kotlin con componentes de la arquitectura de Android.

Más información
A medida que los datos se hacen más complejos, quizás decidas tener una clase por separado solo para cargar los
datos. El objetivo de ViewModel es encapsular los datos para un controlador de IU a Tn de que estos sobrevivan a los
cambios de conTguración. Si quieres obtener más información para cargar, conservar y administrar datos durante
cambios de conTguración, consulta Cómo guardar estados de IU.

La Guía para la arquitectura de apps de Android sugiere crear una clase de repositorio para administrar estas funciones.

Recursos adicionales
Para obtener más información sobre la clase ViewModel , consulta los siguientes recursos.

Ejemplos

Muestra básica de los componentes de la arquitectura Android

Sunbower, una app de jardinería que ilustra las prácticas recomendadas de desarrollo de Android con
Android Jetpack

Codelabs

Android Room con una vista (Java) (Kotlin)

Codelab de componentes que tienen en cuenta el ciclo de vida de Android

Blogs

ViewModels: un ejemplo simple

ViewModels: Persistence, onSaveInstanceState(), restauración del estado de IU y cargadores

ViewModels y LiveData: patrones y antipatrones

DesmitiTcación de Kotlin: explicación breve de la sintaxis de Lambda

DesmitiTcación de Kotlin: funciones del alcance

DesmitiTcación de Kotlin: cuándo usar accesos personalizados

Carga de datos teniendo en cuenta el ciclo de vida con componentes de arquitectura

Videos

Android Jetpack: ViewModel

¿Te resultó útil?

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks
of Oracle and/or its aeliates.

Last updated 2022-07-08 UTC.

Twitter YouTube LinkedIn


Sigue a @AndroidDev Busca Android Developers en Conectarse con la comunidad
en Twitter YouTube de desarrolladores de Android
en LinkedIn

M ÁS A N D RO I D DESCUBRE D I S P O S I T I VO S VERSIONES D O C U M E N TAC I Ó N Y AS I ST E N C I A


A N D RO I D D E S CA RG AS
Android Videojuegos Android 11 Informar sobre un error
Pantallas grandes Guía de Android Studio en la plataforma
Android para empresas Aprendizaje automático Android 10
Wear OS Guías para Informar sobre un error
Seguridad Privacidad Pie desarrolladores en la documentación
Android TV
Código abierto 5G Oreo Referencia de API Google Play support
Android para vehículos
Noticias Nougat Descargar Studio Participar en los estudios
Android Things de investigación
Blog Marshmallow NDK de Android
Dispositivos con
Podcasts Chrome OS Lollipop

KitKat

Android Chrome Firebase Google Cloud Platform Todos los productos

Privacidad | Licencia | Lineamientos de marca Recibe noticias y sugerencias por correo electrónico Suscribirse Language
)

También podría gustarte