パート 2: アプリのライフサイクルと状態を管理する (HTML)

Applies to Windows only

複数のアプリを起動してそれらを切り替える際、速度の低下やバッテリ切れを心配する必要はありません。 これは、バックグラウンドで実行中のアプリは自動的に中断 (場合によっては終了) されるためです。アプリが中断または終了されたときにアプリの状態を保存し、アプリが再起動したときに状態を復元すると、アプリの実行が停止しなかったように見せることができます。

手順:

  • さまざまなローミング ストレージを使って状態を保存する
  • 次回のアプリ起動時にアプリの状態を復元する

ヒント  

チュートリアルを省略して、すぐにコードを参照する場合は、JavaScript の概要のチュートリアル シリーズ向けのコードに関するページをご覧ください。

はじめに...

  • これはシリーズの 2 番目のチュートリアルです。このチュートリアルを始める前に、「パート 1: "Hello, world!" アプリを作成する」をご覧ください。パート 1 で作ったコードを使って説明を開始します。

アプリのライフサイクルについて

前回のチュートリアルでは、default.js ファイルにアプリのアクティブ化を処理するコードを記述する方法について説明しました。コードの説明を始める前に、アプリのライフサイクルについて簡単に説明します。

ある時点において、アプリは実行していない状態、実行中、または中断の状態にあります。

アプリのライフサイクル

ユーザーがアプリを切り替えた場合、またはデバイスが低電力状態に切り替わった場合にアプリを中断できます。 ユーザーがすばやく確実にアプリを切り替えて再開できるよう、中断しているアプリはメモリに常駐を続けます。 アプリが中断してから再開する場合、ずっと実行していたかのように見せるための追加のコードを記述する必要はありません。

他のアプリにメモリを解放したり電力を節約するために、オペレーティング システムは中断しているアプリをいつでも終了できます。終了したアプリは実行を停止し、メモリからアンロードされます。

ユーザーが Alt キーを押しながら F4 キーを押すか、ジェスチャを使ってアプリを閉じた場合、アプリは 10 秒間中断された後、終了されます。

オペレーティング システムは中断したアプリには通知しますが、終了したアプリには追加の通知は行いません。 このため、アプリでは中断イベントを処理して、すぐに状態を保存し、排他リソースとファイル ハンドルを解放する必要があります。

優れたユーザー エクスペリエンスを実現するには、アプリの実行が停止しなかったように見えることが必要です。このため、アプリではユーザーが入力したデータや設定の変更などを保持する必要があります。このため、アプリを中断する場合はオペレーティング システムによって終了された場合に備えて、後で復元できるようにアプリの状態を保存する必要があります。

アプリではアプリ データセッション データの 2 種類のデータを管理します。

次の手順では、これらの種類のデータを保存するようにアプリを更新する方法について説明します。どのような状態を保存する必要があるでしょうか。現在ユーザーが変更できる項目は、名前の入力だけです。また、[Say "Hello"] ボタンをクリックして、ユーザーに合わせたあいさつを生成できます。

手順 1: アプリ データの保存

セッション間で保持されるアプリ データには、ユーザーが常にアクセスできるようにしておく必要があります。このアプリでは、nameInput input ボックスの value がアプリ データ (ユーザーが実行したときに必ずアプリに表示される設定) です。 アプリが suspending イベント ハンドラーのコードを実行できる時間は最大 5 秒間しかありません。このため、アプリが中断 (または終了) するまでに重要なアプリ データを固定記憶域に確実に保存する必要があります。それを行う最も良い方法は、アプリ データが変更されたときに少しずつ保存することです。

アプリ データの管理に役立つ Windows.Storage.ApplicationData オブジェクトを使うことができます。 このオブジェクトの roamingSettings プロパティは ApplicationDataContainer を返します。このローミング ApplicationDataContainer を使って、セッション間で保持されるユーザー データを格納できます。では、ユーザーが入力した名前と評価をローミング ApplicationDataContainer に格納しましょう。

  このチュートリアルでは、roamingSettings を使う方法について説明します。ローミング設定のアプリ データ コンテナーを使って、データを保存すると、ユーザーが複数のコンピューターから簡単にアクセスできます。基本的に、データはバックグラウンドでクラウドにアップロードされます。ローカル設定のアプリ データ コンテナー (localSettings) を使うこともできますが、それはコンピューター固有の情報を保存する場合にのみ使います。

ここでは、「パート 1: "Hello, world!" アプリを作成する」のコードを使って説明を開始します。

Hh986966.wedge(ja-jp,WIN.10).gifアプリ データを保存するには

  1. default.js ファイルで、nameInput input ボックスの change イベントのイベント ハンドラーを作成します。イベント ハンドラーに nameInputChanged という名前を付けます。 次のコードを、パート 1 で作成した buttonClickHandler のすぐ後に追加します。

    
        function nameInputChanged(eventInfo) {
    
        }
    
    
  2. eventInfo オブジェクトの srcElement プロパティを使って、nameInput コントロールにアクセスします (srcElement プロパティは、イベントを起動した要素を取得します)。

    
        function nameInputChanged(eventInfo) {
            var nameInput = eventInfo.srcElement;
    
        }
    
    
  3. 次のように、ローミング設定の ApplicationDataContainer にユーザーの名前を保存します。

    1. Windows.Storage.ApplicationData.current プロパティを呼び出して、アプリの ApplicationData オブジェクトを取得します。
    2. 次に、ApplicationData オブジェクトの roamingSettings プロパティを呼び出して、ローミング設定の ApplicationDataContainer を取得します。

    これで、どのようなキーを使ったユーザーの名前でも格納できます。ユーザーの名前を "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. パート 1: "Hello, world" アプリを作成する」では、onactivated イベント ハンドラーを使って独自のイベント ハンドラーを登録しました。 ここで、nameInputChanged イベント ハンドラーを 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 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. 次に、Rating コントロールの状態が変更されたときにその状態を保存します。必要な作業は、パート 1 で作成したイベント ハンドラーを更新して、値を roamingSettings アプリ コンテナーに保存するようにすることだけです。評価を 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;
        }
    
    

これで、アプリを実行してテキスト ボックスに名前を入力すると、その名前と評価が保存されます。ただし、アプリを再起動しても名前は再表示されません。これには、保存した状態を読み込むコードを追加する必要があります。この処理は手順 3. で行います。その前に、セッション データを保存する方法について説明します。

手順 2: セッション データの保存

セッション データとは、アプリの現在のユーザー セッションに関連する一時的なデータです。閉じるジェスチャを使うか、Alt キーを押しながら F4 キーを押してアプリを終了したとき、コンピューターを再起動したとき、コンピューターからログオフしたとき、セッションは終了します。 このアプリでは、greetingOutput divinnerText がセッション データです。アプリが Windows により中断され、終了した場合にのみ、これを復元します。セッション データを格納するには WinJS.Application.sessionState オブジェクトを使います。

セッション データはどのようなタイミングで保存するのでしょうか。default.js ファイルにある oncheckpoint イベント ハンドラーを使うことができます。Windows が今まさにアプリを中断しようとすると、このイベント ハンドラーが呼び出されます。ただし、アプリ データの場合と同じように、セッション データも変更されたときに少しずつ保存することをお勧めします。そのため、ユーザーが ["Say Hello"] ボタンをクリックしたときに、セッション データを保存するようにします。

Hh986966.wedge(ja-jp,WIN.10).gifセッション データを保存するには

  • default.js で、「パート 1: "Hello, world!" アプリを作成する」で作成した buttonClickHandler 関数を更新し、ユーザーに合わせたあいさつを格納できるようにします。

    ユーザーに合わせたあいさつはセッションで保存すればよいため、これを WinJS.Application.sessionState オブジェクトに格納します。sessionState オブジェクトを使うには、プロパティを追加してその値を設定します。 このプロパティに 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;
        }
    
    

アプリが終了する前の状態を保存するために必要な操作はこれだけです。ここからは、次回のアプリ起動時にアプリの状態を復元する方法について説明します。

手順 3: アプリの状態の復元

アプリのアクティブ化を処理する onactivated イベント ハンドラーのコードを詳しく調べてみましょう。

コードはまず、アプリへの参照を取得して app という名前の変数に格納します。 次に、Windows.ApplicationModel.Activation 名前空間を参照する activation という名前の変数を作成します。これらの手順は両方とも完全に省略可能で、アプリや Windows.ApplicationModel.Activation 名前空間を参照する際の入力を減らすのに役立ちます。


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


次に、activated イベント ハンドラーを定義します。 このハンドラーは発生したばかりのアクティブ化の種類をチェックします。これが動作するのは、アクティブ化が launch アクティブ化の場合だけです。別の種類のアクティブ化が発生した場合は何も実行しません。

(イベント ハンドラーは他の種類のアクティブ化に対応するように拡張できますが、このチュートリアルでは説明していません。詳しくは、「アプリケーションのライフサイクル」をご覧ください。)



    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.
            }


前の実行状態が terminated の場合は、アプリが最後に実行されたときに、Windows によって正常に中断されてから終了したことを意味します。アプリが終了されなかった場合、ハンドラーは初めて起動されているかのようにアプリを処理します。

最後に、ハンドラーは WinJS.UI.processAll メソッドと、イベント ハンドラーを登録するために追加したコードを呼び出します。このコードは前の実行状態に関係なく、アプリが起動するたびに呼び出されます。



            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);

            }));

        }
    };

これで onactivated イベント ハンドラーの動作が明らかになったので、これを使ってアプリの状態を復元しましょう。

Hh986966.wedge(ja-jp,WIN.10).gifアプリの状態を復元するには

  1. previousExecutionStateterminated の場合は、ユーザーに合わせたあいさつを読み込みます。

    else 句のコメントには、"アプリの状態を復元する" と記述されています。WinJS.Application.sessionState.greetingOutput に値があるかどうかを調べます。 値がある場合は、greetingOutput div 要素を取得して、あいさつを表示します。

    
        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. 今度は、ユーザーの名前と評価を読み込みます。 ユーザー名と評価のデータは複数のセッション間で保持するため、roamingSettings アプリ データ コンテナーに格納しました。ユーザー名と評価が存在する場合に、アプリ データ コンテナーを取得してユーザー名と評価を表示するコードを追加しましょう。

    このコードは、前回の実行時にアプリがどのようにシャットダウンされたかに関係なく実行されます (セッション データの前の実行状態のみをチェックする必要があります)。このため、アプリの前の実行状態をチェックする if 句の外に追加します。WinJS.UI.processAllthen ハンドラー内にそのコードを追加し、そこでイベントを登録します。

    
        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;
                    }
    
                }));
    
            }
        };
    
    

これでアプリをビルドし、実行して、セッション状態がどのように保存され、復元されるかどうかを確認できます。これまでは、Microsoft Visual Studio のデバッグ モードでアプリを実行し、[デバッグの停止] をクリックして停止することでアプリをテストしてきました。しかし、こうするとアプリが通常どおり終了するため、Suspending イベントは発生しません。さいわい、Visual Studio ではアプリの中断、終了、復元をシミュレートできます。

Hh986966.wedge(ja-jp,WIN.10).gifVisual Studio でアプリの中断、終了、復元をシミュレートするには

  1. F5 キーを押して、デバッグ モードでアプリを実行します。
  2. 入力ボックスに名前を入力し、"[Say "Hello"]" をクリックします。あいさつが表示されます。
  3. Visual Studio に戻るには、Alt キーを押しながら Tab キーを押します。
  4. [デバッグの場所] ツール バーの [中断] の横のドロップダウン メニューを開きます。

    [デバッグ] ツール バーはデバッガーの実行中、既定で表示されます。表示されない場合は、[表示][ツール バー][デバッグの場所] の順にクリックして表示します。

    [中断とシャットダウン] ボタン

  5. [中断とシャットダウン] をクリックします。

    Visual Studio によってアプリの中断と終了がシミュレートされるため、Suspending イベントが発生し、状態管理のコードが実行されます。

  6. F5 キーを押してアプリを再び実行します。アプリの前の状態が復元されます。

要約

これで、チュートリアルは終わりです。アプリのライフサイクルを管理し、状態を保存する方法について説明しました。このチュートリアルでは、アプリの状態を保存するための 2 つの方法について説明しました。状態を保存するためのその他の方法については、「アプリ データの管理」および「状態の効率的な操作」をご覧ください。

サンプルのダウンロード

行き詰まった場合や、作業を確認する場合は、JavaScript の概要のページに関連するサンプルをダウンロードしてください。

次の手順

次回のチュートリアルでは、より複雑なアプリを作成する方法について説明します。「パート 3: PageControl オブジェクトとナビゲーション」をご覧ください。

関連トピック

JavaScript の概要のチュートリアル シリーズ向けのコードに関するページ
HTML、CSS、JavaScript での Windows 8 アプリのプログラミング (ebook)

 

 

表示:
© 2015 Microsoft