¿Cómo sobrevive el ViewModel a los cambios de configuración, y qué ocurre realmente durante la muerte del proceso?
Esta pregunta separa a quienes solo han visto sobrevivir una rotación de quienes entienden que la muerte del proceso destruye el ViewModel por completo y depende de un mecanismo totalmente distinto para recuperarse.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
¿Cómo sobrevive el ViewModel a los cambios de configuración, y qué ocurre realmente durante la muerte del proceso?
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.#La pregunta detrás de la pregunta
"¿Cómo sobrevive el ViewModel a la rotación?" suena a una pregunta trivial de ciclo de vida, pero la respuesta que realmente distingue a un candidato senior es la que se niega a tratar el "cambio de configuración" y la "muerte del proceso" como el mismo evento. No lo son. A uno de ellos el ViewModel sobrevive gratis. Al otro, el ViewModel se destruye por completo, y lo que te salva es un mecanismo totalmente distinto — SavedStateHandle escribiendo en un Bundle que mantiene vivo el sistema operativo, no tu aplicación. Confundir los dos es el error más común que cometen los candidatos en esta pregunta, y es exactamente el tipo de bug que llega a producción: código que solo prueba la rotación y asume que ya cubrió la "restauración de estado".
#Cambio de configuración: la Activity muere, el ViewModel no
Un cambio de configuración — rotar la pantalla, cambiar entre modo claro y oscuro, cambiar de idioma, redimensionar a multi-ventana — le indica al sistema que recursos como el layout o los drawables podrían necesitar recargarse, así que la respuesta por defecto de Android es destruir y recrear la Activity (o el Fragment) por completo. Se ejecutan tanto onDestroy() como onCreate(). Pero antes de destruir la Activity antigua, el framework llama a un gancho interno retenido (históricamente onRetainNonConfigurationInstance(), hoy envuelto por la maquinaria de ViewModelStore) que entrega el ViewModelStore — y cada ViewModel dentro de él — a la nueva instancia de la Activity en lugar de descartarlo. Nada del ViewModel se serializa, nada se escribe a disco; es literalmente el mismo objeto en memoria, mantenido vivo por una referencia que el framework hace pasar silenciosamente a través de la recreación. Por eso un StateFlow a mitad de una llamada de red, o una lista que ya cargaste, simplemente siguen ahí cuando la nueva Activity se suscribe a ellos — nunca hubo un hueco.
#Muerte del proceso: todo muere de verdad
La muerte del proceso es un evento completamente distinto. Cuando tu app pasa a segundo plano y el sistema necesita memoria, puede matar el proceso entero sin más — no solo la Activity, sino el proceso, incluyendo cada objeto del heap. El ViewModelStore desaparece. Cada instancia de ViewModel desaparece. No queda nada en memoria que "reanudar". Cuando el usuario vuelve más tarde a tu app (por ejemplo, desde la pantalla de Recientes), Android arranca un proceso completamente nuevo, y el framework recrea la Activity como si fuera un arranque en frío normal — salvo que le entrega a onCreate() un Bundle que había estado guardando, producido antes por onSaveInstanceState(), justo antes de que la Activity fuera eliminada. Todo lo que recuperas tras la muerte del proceso llega a través de ese Bundle. Todo lo demás — cualquier cosa que solo vivía en un grafo de objetos activo — desaparece y hay que recargarlo desde una fuente de verdad real: una base de datos, una llamada de red, disco.
#Dónde encaja SavedStateHandle
SavedStateHandle es el puente que le permite a un ViewModel participar en ese mecanismo de Bundle sin que el propio ViewModel necesite saber nada sobre onSaveInstanceState ni sobre Bundle. Cuando solicitas un ViewModel mediante by viewModels(), Jetpack conecta un SavedStateHandle (a través de SavedStateViewModelFactory) que se rellena automáticamente desde el Bundle restaurado si el proceso fue eliminado, o que llega vacío si se trata de un primer arranque genuino. Se lee y se escribe en él como si fuera un Map combinado con un Flow — savedStateHandle.getStateFlow("query", "") — y lo que guardes ahí se pliega dentro del mismo Bundle que el sistema guarda en tu nombre. Y esto es crucial: es el único de los dos mecanismos de supervivencia que importa para la muerte del proceso: un campo cualquiera del ViewModel desaparece tras la muerte del proceso, pero un valor leído desde SavedStateHandle vuelve.
#Por qué no puedes meter todo en SavedStateHandle
El Bundle que respalda a SavedStateHandle se transporta a través del mecanismo de IPC Binder de Android para entregarse al proceso de ActivityManager, y las transacciones de Binder comparten un búfer pequeño en todo el proceso — se suele citar una cifra cercana a 1MB, aunque el límite real es por proceso y no está documentado oficialmente como un número fijo. Si metes una lista grande, un bitmap o cualquier cosa no trivial en un SavedStateHandle, corres el riesgo de una TransactionTooLargeException que puede tumbar la app en onSaveInstanceState, a veces solo en ciertos dispositivos o versiones de Android, lo que la convierte en un bug muy difícil de detectar en pruebas. La regla que te mantiene a salvo: SavedStateHandle es para piezas pequeñas de estado de UI transitorio, Parcelable o de tipos primitivos — una búsqueda, el índice de una pestaña seleccionada, una posición de scroll, un campo de formulario en curso — nunca para el conjunto de datos real. El conjunto de datos pertenece a una base de datos o una caché, y se recarga, no se restaura byte a byte.
#Salir por decisión del usuario no te da ningún Bundle
Otra distinción que conviene tener lista: si el usuario pulsa Atrás hasta que la Activity termina legítimamente, o la desliza fuera de Recientes, Android no lo trata como candidato para restauración — no hay ningún Bundle guardado que recuperar, porque no se espera que la app retome donde la dejó; se espera que arranque de cero. El camino de Bundle-y-restauración es específicamente para cuando el sistema recupera memoria a espaldas del usuario, mientras el usuario todavía espera volver al mismo lugar donde lo dejó. Esa expectativa es la razón entera por la que existe el mecanismo.
🧠 Check your understanding
0/3 · 0/3 answered1. Durante un cambio de configuración (por ejemplo, rotar la pantalla), ¿qué le ocurre a la instancia del ViewModel?
2. ¿Qué se destruye durante la muerte del proceso que sí sobrevive a un simple cambio de configuración?
3. ¿Por qué no deberías guardar una lista grande de elementos obtenidos directamente en SavedStateHandle?