La restauración de estado (State Restoration) es un mecanismo de los sistemas operativos móviles que permite guardar y restaurar la interfaz de usuario de una aplicación después de reiniciarla o minimizarla. El sistema guarda el estado de la UI en la memoria o almacenamiento persistente y lo restaura al reabrirla. Según Android Developers (2025), State Restoration es imprescindible para las aplicaciones que buscan una experiencia de usuario de calidad. State Restoration es fundamental para evitar la pérdida de datos cuando una aplicación finaliza inesperadamente.
Puntos clave
State Restoration (restauración de estado) es un mecanismo del sistema que permite guardar el estado actual de la interfaz de usuario de una aplicación y restaurarlo después de su finalización o reinicio. Cuando un usuario minimiza una aplicación o el sistema la cierra para liberar recursos, State Restoration captura los parámetros clave de la UI y los guarda en almacenamiento cifrado.
Sin State Restoration, los usuarios pierden todos los datos no guardados al cambiar entre aplicaciones. Por ejemplo, un formulario de comentarios rellenado, una consulta de búsqueda larga o una lista de noticias visualizada parcialmente — todo esto desaparece al reiniciar. State Restoration resuelve este problema capturando automáticamente el estado del ViewController o Activity en el momento de minimizar.
El mecanismo funciona a nivel de sistema y es compatible con ambas plataformas móviles principales. iOS proporciona State Restoration a través de NSUserActivity y el protocolo UIStateRestoring, mientras que Android lo proporciona a través de SavedStateHandle en los componentes arquitectónicos Jetpack y ViewModel. La implementación difiere, pero el concepto es idéntico.
El proceso de State Restoration se divide en dos fases: guardado y restauración. En la fase de guardado, el sistema llama a los métodos correspondientes del ciclo de vida, en los que la aplicación debe serializar el estado actual de la UI en una representación compacta. En la fase de restauración, el sistema devuelve los datos guardados y la aplicación los deserializa para restaurar la UI.
El guardado lo inicia el sistema cuando la aplicación pasa a segundo plano o recibe una señal de finalización inminente. En iOS se llama al método encodeRestorableState de UIViewController; en Android se llama a onSaveInstanceState de Activity o se guarda mediante SavedStateHandle. Los datos se serializan en un formato que admite tipos primitivos: cadenas, números, matrices de bytes y objetos Parcelable.
La cantidad de datos guardados debe ser mínima — el sistema impone límites en el tamaño del paquete de estado guardado. En Android, el límite es de aproximadamente 50 KB por proceso. Superar el límite provoca una excepción TransactionTooLargeException. Por lo tanto, los arquitectos recomiendan guardar solo identificadores y claves, y cargar los datos completos desde el almacenamiento persistente al restaurar.
Durante la restauración, el sistema pasa el paquete de datos guardados a la aplicación en el momento del inicio. En iOS se llama al método decodeRestorableState; en Android se usa onRestoreInstanceState o la lectura desde SavedStateHandle. La aplicación extrae los identificadores y claves del paquete y restaura la UI: posición de desplazamiento, elementos seleccionados, datos introducidos.
Es importante tener en cuenta que la restauración puede ocurrir en un nuevo proceso. Si la aplicación se descargó completamente de la memoria, el proceso se crea de nuevo y todos los objetos en memoria están ausentes. Por lo tanto, el estado debe ser serializable e independiente del contexto de ejecución de la sesión anterior. Esto es especialmente crítico para formularios grandes con múltiples campos de entrada e interfaces largas de varias páginas.
class MainActivity : AppCompatActivity() {
private var searchQuery: String = ""
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("search_query", searchQuery)
}
override fun onRestoreInstanceState(savedState: Bundle) {
super.onRestoreInstanceState(savedState)
searchQuery = savedState.getString("search_query", "")!!
restoreSearchUI(searchQuery)
}
}
La implementación de State Restoration difiere significativamente entre plataformas. iOS utiliza un enfoque declarativo a través de storyboards y protocolos UIKit, mientras que Android utiliza un enfoque imperativo a través de métodos del ciclo de vida de Activity y componentes arquitectónicos Jetpack. La elección del enfoque depende de la plataforma objetivo y la arquitectura de la aplicación.
En iOS, State Restoration se basa en tres componentes: UIApplication gestiona el proceso general, UIViewController implementa el protocolo UIStateRestoring y NSUserActivity almacena datos para la restauración de la navegación. Para habilitarlo, debe establecer restorationIdentifier en UIViewController e implementar encodeRestorableState y decodeRestorableState.
iOS guarda automáticamente el estado del controlador de navegación (UINavigationController) y todos los ViewControllers anidados si tienen establecido un restorationIdentifier. El sistema gestiona la pila de navegación y la restaura a su estado original. Sin embargo, los datos dentro de los controladores (texto introducido, posición de desplazamiento) deben ser guardados explícitamente por el desarrollador.
En Android, el enfoque moderno de State Restoration se basa en SavedStateHandle — un componente de la biblioteca AndroidX Lifecycle. SavedStateHandle es accesible dentro de ViewModel y guarda y restaura automáticamente los datos en cambios de configuración (rotación de pantalla) y reinicio del proceso. Los datos se almacenan en un Bundle y se serializan automáticamente.
SavedStateHandle se comporta como un almacén clave-valor con soporte para LiveData. En cambios de configuración, los datos se guardan y restauran automáticamente. Para admitir el reinicio del proceso, el ViewModel debe crearse mediante SavedStateViewModelFactory — esto permite que el ViewModel sobreviva a la finalización completa de la aplicación.
class SearchViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
companion object {
private val KEY_QUERY = string("search_query")
}
fun getSearchQuery(): String? = savedStateHandle[KEY_QUERY]
fun saveSearchQuery(query: String) {
savedStateHandle[KEY_QUERY] = query
}
}
La implementación práctica de State Restoration requiere considerar varios aspectos: elegir el almacenamiento adecuado, determinar la cantidad de datos a guardar y probar varios escenarios de finalización. Veamos una implementación paso a paso para una aplicación Flutter utilizando el paquete state_restoration.
class RestorableSearchField extends RestorableProperty<String> {
String _value = '';
@override
String get value => _value;
@override
void set value(String newValue) {
if (_value != newValue) {
_value = newValue;
notifyListeners();
}
}
@override
String? toPrimitives() => _value;
@override
void fromPrimitives(String? data) {
_value = data ?? '';
}
}
Al implementar, es importante recordar los límites de guardado. No todos los campos de la UI necesitan restaurarse. La posición de desplazamiento en una lista larga — sí. El estado temporal de una animación — no. El desarrollador debe elegir conscientemente qué datos son críticos para la experiencia del usuario y cuáles se pueden restablecer de forma segura sin perder comodidad.
Probar State Restoration es una tarea independiente que requiere simular la finalización del proceso. En Android, esto se puede hacer mediante el comando adb shell am kill; en iOS, mediante la simulación de finalización en Xcode. Los frameworks de pruebas de UI, como Espresso y XCTest, proporcionan métodos especiales para verificar la restauración del estado.
La primera regla — guarde identificadores, no datos. En lugar de guardar el objeto completo con cien campos, guarde su identificador único y, al restaurar, cargue los datos reales desde la base de datos o API. Esto ahorra espacio en el Bundle y garantiza la frescura de los datos en el momento de la restauración.
La segunda regla — pruebe todos los escenarios. Verifique la restauración después de la rotación de pantalla, después de minimizar y volver una hora después, después de que el sistema termine la aplicación por falta de memoria. Cada escenario puede comportarse de manera diferente según el estado del sistema operativo y los recursos disponibles.
La tercera regla — utilice mecanismos del sistema, no personalizados. iOS y Android proporcionan API integradas para State Restoration optimizadas para su plataforma específica. Una implementación personalizada mediante SharedPreferences o UserDefaults puede provocar problemas de sincronización y comportamientos inesperados durante la restauración.
La cuarta regla — maneje la ausencia de estado. En el primer inicio o después de borrar datos, el estado puede estar ausente. La UI debe funcionar correctamente en su estado inicial sin lanzar excepciones. Verifique todos los datos guardados como nulos antes de usarlos y proporcione valores predeterminados.
La quinta regla — documente las claves guardadas. Cuando un proyecto tiene docenas de pantallas y cada una guarda varios campos, sin una gestión centralizada de claves surge el caos. Cree una única clase o archivo con constantes de clave para State Restoration en cada módulo. Esto simplifica el mantenimiento y evita sobrescrituras accidentales de datos durante la refactorización.
Preguntas frecuentes
State Restoration es un mecanismo para guardar y restaurar la interfaz de usuario de la aplicación después de reiniciarla o minimizarla, evitando la pérdida de datos y el contexto del usuario.
State Restoration guarda el estado temporal de la UI (posición de desplazamiento, datos de formulario), mientras que una base de datos almacena datos persistentes del usuario. State Restoration utiliza mecanismos del sistema (Bundle, NSData) con limitaciones de volumen.
Use SavedStateHandle en ViewModel de AndroidX Lifecycle. Guarda datos automáticamente al minimizar y los restaura al volver. Para soporte completo de reinicio, use SavedStateViewModelFactory.
Establezca restorationIdentifier en UIViewController e implemente los métodos encodeRestorableState y decodeRestorableState. Para la navegación, use NSUserActivity conservando la ruta en la pila de controladores.
Guarde identificadores, no datos completos: ID del elemento seleccionado, consulta de búsqueda, posición de desplazamiento, estados de interruptores. Evite guardar objetos grandes e imágenes.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también