Parte 2: Administrar el ciclo de vida y el estado de la aplicación (aplicaciones de la Tienda Windows con JavaScript y HTML)

En Windows 8.1 puedes iniciar varias aplicaciones y alternar entre ellas sin tener que preocuparte porque el sistema se ralentice o se agote la batería. Esto es porque el sistema suspende (y a veces finaliza) de forma automática las aplicaciones que se ejecutan en segundo plano. Al guardar el estado de una aplicación cuando se suspende o finaliza, y al restaurar el estado cuando se reinicia, puedes hacer que parezca que la aplicación no ha dejado de ejecutarse en ningún momento.

Aprende a:

  • Guardar estados mediante varios tipos de almacenamiento de roaming
  • Restaurar el estado de las aplicaciones la próxima vez que se inicien

Sugerencia  

Si quieres pasar por alto el tutorial e ir directamente al código, consulta Introducción a JavaScript: código completo de la serie de tutoriales.

Antes de comenzar...

Sobre el ciclo de vida de la aplicación

En el tutorial anterior, describimos cómo el archivo default.js contiene código que controla la activación de la aplicación. Antes de volver al código, hablemos un poco sobre el ciclo de vida de la aplicación.

En cualquier momento dado, una aplicación no está en ejecución, está en ejecución o está suspendida.

Ciclo de vida de la aplicación

Se puede suspender una aplicación cuando el usuario cambia a otra aplicación o cuando Windows entra en modo de bajo consumo. Mientras la aplicación está suspendida, sigue residiendo en la memoria, por lo que los usuarios pueden cambiar entre aplicaciones suspendidas rápidamente y reanudarlas. Cuando se suspende y se vuelve a reanudar la aplicación, no tienes que escribir ningún otro código para hacer que parezca como que ha estado en ejecución todo el tiempo.

Pero Windows también puede finalizar una aplicación suspendida en cualquier momento para liberar memoria para otras aplicaciones o para ahorrar energía. Cuando finaliza tu aplicación, deja de ejecutarse y se descarga de la memoria.

Cuando el usuario cierra una aplicación presionando Alt+F4 o mediante el gesto de cierre, la aplicación se suspende durante 10 segundos y después finaliza.

Windows notifica a la aplicación cuando la suspende, pero no ofrece ninguna otra notificación cuando la finaliza, lo que significa que tu aplicación debe controlar el evento de suspensión y usarlo para guardar su estado y liberar inmediatamente sus recursos exclusivos e identificadores de archivos.

Para crear una buena experiencia de usuario, queremos que parezca como si la aplicación no hubiera dejado nunca de ejecutarse. Esto quiere decir que la aplicación necesita mantener cualquier dato escrito por el usuario, configuración cambiada, etc. Así, tenemos que guardar el estado de la aplicación cuando la suspendemos, por si Windows la finaliza, para poder restaurar su estado más adelante.

Existen dos tipos de datos que puedes administrar en la aplicación: datos de la aplicación y datos de sesión.

En los pasos siguientes, aprenderemos a actualizar nuestra aplicación para guardar estos tipos de datos. ¿Qué estado necesitamos guardar? Ahora mismo, lo único que el usuario puede cambiar es la entrada de su nombre y su clasificación. El usuario también puede hacer clic en el botón Say "Hello" para generar un saludo personalizado.

Paso 1: Guardar los datos de la aplicación

Los datos de la aplicación persisten durante las sesiones y siempre deben estar accesibles al usuario. En nuestra aplicación, el value del cuadro nameInput input son datos de la aplicación—, una configuración que debe aparecer en la aplicación cuando el usuario la ejecuta. Tu aplicación solo tiene cinco segundos para ejecutar código en el controlador de eventos de suspensión, por lo que tienes que asegurarte de que los datos importantes de la aplicación se guardan en almacenamiento persistente en el momento en que se suspende la aplicación (o se finaliza). La mejor forma de hacerlo es guardar los datos de la aplicación a medida que van cambiando.

Windows ofrece un objeto Windows.Storage.ApplicationData para ayudarte a administrar los datos de la aplicación. Este objeto tiene una propiedad roamingSettings que devuelve un ApplicationDataContainer. Podemos usar este ApplicationDataContainer de roaming para almacenar los datos de usuario que persisten durante las sesiones. Guardemos el nombre de usuario y la clasificación en el ApplicationDataContainer de roaming mientras el usuario lo escribe.

Nota  Este tutorial muestra cómo usar roamingSettings. El contenedor de datos de la aplicación de configuración de roaming facilita el almacenamiento de datos de manera accesible al usuario en varios equipos. Básicamente, los datos se cargan en la nube en segundo plano. También puedes usar el contenedor de datos de la aplicación de configuración local (localSettings), pero solo deberías usarlo cuando quieras almacenar información específica del equipo.

Empezamos con el código de Parte 1: Crear una aplicación "Hello, world!".

Hh986966.wedge(es-es,WIN.10).gifPara guardar los datos de la aplicación

  1. En el archivo default.js, crea un controlador de eventos para el evento change del cuadro nameInput input. Nombra al controlador de eventos nameInputChanged. Agrega este código justo después del buttonClickHandler que creamos en la Parte 1.

    
        function nameInputChanged(eventInfo) {
    
        }
    
    
  2. Usa la propiedad srcElement del objeto eventInfo para acceder al control nameInput. (La propiedad srcElement recupera el elemento que activó el evento.)

    
        function nameInputChanged(eventInfo) {
            var nameInput = eventInfo.srcElement;
    
        }
    
    
  3. Guarda el nombre de usuario en el ApplicationDataContainer para la configuración de roaming:

    1. Llama a la propiedad Windows.Storage.ApplicationData.current para obtener el objeto ApplicationData de la aplicación.
    2. Después llama a la propiedad roamingSettings del objeto ApplicationData para obtener el ApplicationDataContainer para la configuración de roaming.

    Ahora podemos guardar el nombre del usuario con cualquier clave que queramos. Guardemos el nombre de usuario como "userName".

    
        function nameInputChanged(eventInfo) {
            var nameInput = eventInfo.srcElement;
    
            // Store the user's name for multiple sessions.
            var appData = Windows.Storage.ApplicationData.current;
            var roamingSettings = appData.roamingSettings;
            roamingSettings.values["userName"] = nameInput.value;
        }
    
    
  4. En Parte 1: Crear una aplicación "Hello World!", usamos el controlador de eventos onactivated para registrar nuestros controladores de eventos. Ahora, vamos a agregar algo de código para registrar el controlador de eventos nameInputChanged con el control nameInput.

    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {
    
                    // Retrieve the div that hosts the Rating control.
                    var ratingControlDiv = document.getElementById("ratingControlDiv");
    
                    // Retrieve the actual Rating control.
                    var ratingControl = ratingControlDiv.winControl;
    
                    // Register the event handler. 
                    ratingControl.addEventListener("change", ratingChanged, false);
    
                    // Retrieve the button and register our event handler. 
                    var helloButton = document.getElementById("helloButton");
                    helloButton.addEventListener("click", buttonClickHandler, false);
    
                    // Retrieve the input element and register our
                    // event handler.
                    var nameInput = document.getElementById("nameInput");
                    nameInput.addEventListener("change", nameInputChanged);
    
                }));
    
            }
        };
    
    
  5. Guardemos ahora el estado del control Rating cuando cambie. Solo tenemos que actualizar el controlador de eventos que creamos en la Parte 1 para guardar el valor en nuestro contenedor de la aplicación roamingSettings. Vamos a guardar la clasificación como greetingRating.

    
        function ratingChanged(eventInfo) {
    
            var ratingOutput = document.getElementById("ratingOutput");
            ratingOutput.innerText = eventInfo.detail.tentativeRating;
    
            // Store the rating for multiple sessions.
            var appData = Windows.Storage.ApplicationData.current;
            var roamingSettings = appData.roamingSettings;
            roamingSettings.values["greetingRating"] = eventInfo.detail.tentativeRating;
        }
    
    

Cuando ejecutes la aplicación ahora, tu nombre y la clasificación se guardarán en cuanto los escribas en el cuadro de texto. Pero, cuando vuelvas a iniciar la aplicación, tu nombre no volverá a aparecer. Esto es porque tenemos que agregar código para cargar el estado que acabamos de guardar. Esto lo hacemos en el paso 3. Pero antes de hacerlo, veamos cómo guardar nuestros datos de sesión.

Paso 2: Guardar los datos de sesión

Los datos de la sesión son datos temporales relevantes para la sesión actual del usuario en tu aplicación. Una sesión finaliza cuando el usuario cierra la aplicación mediante el gesto de cierre o Alt + F4, reinicia el equipo o cierra sesión en el equipo. En nuestra aplicación, el innerText de greetingOutput div son datos de sesión. Solo lo restauramos si Windows suspende y finaliza la aplicación. Para almacenar los datos de la sesión, usa el objeto WinJS.Application.sessionState.

¿Cuándo tenemos que guardar nuestros datos de sesión? El archivo default.js contiene un controlador de eventos oncheckpoint que podemos usar. Se llama a este controlador de eventos cuando Windows está a punto de suspender nuestra aplicación. Sin embargo, es mejor guardar los datos de sesión a medida que van cambiando, como hicimos con los datos de la aplicación, así que guardaremos nuestros datos de sesión cuando el usuario haga clic en el botón "Say Hello".

Hh986966.wedge(es-es,WIN.10).gifPara guardar los datos de sesión

  • En default.js, actualiza la función buttonClickHandler que creaste en Parte 1: Crear una aplicación "Hello, world!" para que almacene los saludos personalizados.

    Como el saludo personalizado solo tiene que guardarse para la sesión, lo guardamos en un objeto WinJS.Application.sessionState. Para usar el objeto sessionState, basta con agregar una propiedad y establecer el valor de dicha propiedad. Llamemos a la propiedad greetingOutput.

    
        function buttonClickHandler(eventInfo) {
    
            var userName = document.getElementById("nameInput").value;
            var greetingString = "Hello, " + userName + "!";
            document.getElementById("greetingOutput").innerText = greetingString;
    
            // Save the session data. 
            WinJS.Application.sessionState.greetingOutput = greetingString;
        }
    
    

Esto es todo lo que tenemos que hacer para guardar el estado de la aplicación antes de que esta finalice. Ahora necesitamos aprender a restaurar el estado de nuestra aplicación la próxima vez que el usuario la inicie.

Paso 3: Restaurar el estado de la aplicación

Examinemos con atención el código en el controlador de eventos onactivated que controla la activación de la aplicación.

Lo primero que hace el código es obtener una referencia para nuestra aplicación y guardarla en una variable llamada app. Después crea una variable llamada activation que se refiere al espacio de nombres Windows.ApplicationModel.Activation. Estos dos pasos son completamente opcionales y solo sirven para reducir lo que tienes que teclear para referirte a tu aplicación o el espacio de nombres Windows.ApplicationModel.Activation.


    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;


Después, el código define un controlador de eventos activado. El controlador comprueba el tipo de activación que acaba de ocurrir. Funciona únicamente si la activación es de tipo launch. Cuando se produce otro tipo de activación, el controlador no hace nada.

(Puedes expandir el controlador de eventos para que responda a otro tipo de activaciones, pero eso no está cubierto en este tutorial. Si quieres más información, consulta el tema sobre el ciclo de vida de la aplicación).



    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
          

Después, el controlador comprueba el estado de ejecución anterior para ver cómo se cerró la aplicación la última vez.



            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }


Cuando el estado de ejecución anterior es terminated, significa que la última vez que se ejecutó la aplicación, Windows la suspendió correctamente y después la finalizó. Si no finalizó la aplicación, el controlador la trata como si se iniciara por primera vez.

Por último, el controlador llama al método WinJS.UI.processAll y el código que agregamos para registrar nuestros controladores de eventos. Llama a este código cada vez que se inicia la aplicación, sin tener en cuenta su estado de ejecución anterior.



            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll().then(function completed() {

                // Retrieve the div that hosts the Rating control.
                var ratingControlDiv = document.getElementById("ratingControlDiv");

                // Retrieve the actual Rating control.
                var ratingControl = ratingControlDiv.winControl;

                // Register the event handler. 
                ratingControl.addEventListener("change", ratingChanged, false);

                // Retrieve the button and register our event handler. 
                var helloButton = document.getElementById("helloButton");
                helloButton.addEventListener("click", buttonClickHandler, false);

                // Retrieve the input element and register our
                // event handler.
                var nameInput = document.getElementById("nameInput");
                nameInput.addEventListener("change", nameInputChanged);

            }));

        }
    };

Ahora que entendemos lo que hace el controlador de eventos onactivated, lo vamos a usar para restaurar el estado de la aplicación.

Hh986966.wedge(es-es,WIN.10).gifPara restaurar el estado de la aplicación

  1. Cuando el previousExecutionState es terminated, carga nuestro saludo personalizado.

    En la cláusula else donde los comentarios dicen que hay que restaurar el estado de la aplicación, comprueba si WinJS.Application.sessionState.greetingOutput tiene un valor. Si tiene un valor, recupera el elemento div greetingOutput y úsalo para mostrar el saludo.

    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
    
                    // Retrieve our greetingOutput session state info, 
                    // if it exists. 
                    var outputValue = WinJS.Application.sessionState.greetingOutput;
                    if (outputValue) {
                        var greetingOutput = document.getElementById("greetingOutput");
                        greetingOutput.innerText = outputValue;
                    }
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {
    
                    // Retrieve the div that hosts the Rating control.
                    var ratingControlDiv = document.getElementById("ratingControlDiv");
    
                    // Retrieve the actual Rating control.
                    var ratingControl = ratingControlDiv.winControl;
    
                    // Register the event handler. 
                    ratingControl.addEventListener("change", ratingChanged, false);
    
                    // Retrieve the button and register our event handler. 
                    var helloButton = document.getElementById("helloButton");
                    helloButton.addEventListener("click", buttonClickHandler, false);
    
                    // Retrieve the input element and register our
                    // event handler.
                    var nameInput = document.getElementById("nameInput");
                    nameInput.addEventListener("change", nameInputChanged);
    
                }));
    
            }
        };
    
    
  2. Ahora cargamos el nombre de usuario y la clasificación. Como queremos que los datos del nombre de usuario y la clasificación persistan durante varias sesiones, los almacenamos en el contenedor de datos de la aplicación roamingSettings. Agreguemos algo de código para recuperar el contenedor de datos de la aplicación y mostrar el nombre de usuario y la clasificación, si existen.

    Queremos que este código se ejecute independientemente del modo en que se apagó la aplicación la última vez que se ejecutó (solo necesitamos comprobar el estado de ejecución anterior de los datos de sesión), así que lo agregamos fuera de la cláusula if que comprueba el estado de ejecución anterior de la aplicación. Vamos a agregarlo dentro del controlador then de WinJS.UI.processAll, donde registramos nuestros eventos.

    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
    
                    // Retrieve our greetingOutput session state info, 
                    // if it exists. 
                    var outputValue = WinJS.Application.sessionState.greetingOutput;
                    if (outputValue) {
                        var greetingOutput = document.getElementById("greetingOutput");
                        greetingOutput.innerText = outputValue;
                    }
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {
    
                    // Retrieve the div that hosts the Rating control.
                    var ratingControlDiv = document.getElementById("ratingControlDiv");
    
                    // Retrieve the actual Rating control.
                    var ratingControl = ratingControlDiv.winControl;
    
                    // Register the event handler. 
                    ratingControl.addEventListener("change", ratingChanged, false);
    
                    // Retrieve the button and register our event handler. 
                    var helloButton = document.getElementById("helloButton");
                    helloButton.addEventListener("click", buttonClickHandler, false);
    
                    // Retrieve the input element and register our
                    // event handler.
                    var nameInput = document.getElementById("nameInput");
                    nameInput.addEventListener("change", nameInputChanged);
    
                    // Restore app data. 
                    var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings;
    
                    // Restore the user name.
                    var userName =
                        Windows.Storage.ApplicationData.current.roamingSettings.values["userName"];
                    if (userName) {
                        nameInput.value = userName;
                    }
    
                    // Restore the rating. 
                    var greetingRating = roamingSettings.values["greetingRating"];
                    if (greetingRating) {
                        ratingControl.userRating = greetingRating;
                        var ratingOutput = document.getElementById("ratingOutput");
                        ratingOutput.innerText = greetingRating;
                    }
    
                }));
    
            }
        };
    
    

Ahora puedes crear y ejecutar la aplicación y ver cómo guarda y restaura el estado de la sesión. De momento, has probado la aplicación ejecutándola en modo de depuración y deteniéndola mediante la selección de Detener depuración en Microsoft Visual Studio. Pero esto hace que la aplicación realice un cierre normal y el evento Suspending no se produce. Afortunadamente, Visual Studio te deja simular la suspensión, finalización y restauración de una aplicación.

Hh986966.wedge(es-es,WIN.10).gifPara simular la suspensión, finalización y restauración de una aplicación en Visual Studio

  1. Presiona F5 para ejecutar la aplicación en modo de depuración.
  2. Escribe tu nombre en el cuadro de entrada y haz clic en "Say "Hello"" (Decir "Hola"). Se mostrará el saludo.
  3. Presiona Alt+Tab para regresar a Visual Studio.
  4. Abre el menú desplegable junto al botón Suspender en la barra de herramientas Ubicación de depuración.

    La barra de herramientas Depurar se muestra de forma predeterminada mientras se ejecuta el depurador. Si no la ves, selecciona Ver > Barras de herramientas > Ubicación de depuración para mostrarla.

    Botón de suspensión y apagado

  5. Selecciona Suspend and shutdown (Suspender y cerrar).

    Visual Studio simula la suspensión y finalización de la aplicación, por lo que se produce el evento Suspending y se ejecuta el código de administración del estado.

  6. Presiona F5 para ejecutar la aplicación de nuevo. La aplicación se restaura a su estado anterior.

Resumen

Enhorabuena, ¡ya has acabado con el segundo tutorial! Has aprendido a administrar el ciclo de vida de tu aplicación y a guardar el estado. Este tutorial solo te mostró dos formas de guardar el estado de tu aplicación. Si quieres más información sobre otras formas de guardar el estado, consulta el tema sobre cómo administrar datos de la aplicación y cómo trabajar con el estado de forma eficiente.

Descargar la muestra

¿Te has quedado atascado o quieres revisar tu trabajo? En este caso, descarga las muestras de la introducción a JavaScript.

Pasos siguientes

En la siguiente parte de esta serie de tutoriales, aprenderás a crear una aplicación más compleja. Ve a Parte 3: Navegación y objetos de PageControl.

Temas relacionados

Introducción a JavaScript: código completo de la serie de tutoriales
Programming Windows 8 Apps with HTML, CSS, and JavaScript (libro electrónico)

 

 

Mostrar:
© 2014 Microsoft. Reservados todos los derechos.