Windows Phone 8の高速アプリ再開

高速アプリの結果



Photosハブへの統合に関する前回の記事の続きで、本日、WP8に登場したFast Application Resumeテーマを明らかにし、この機能を使用するために必要なものと利点、およびApp Resumeを使用するためのさまざまなシナリオを検討します。



先を見据えて、写真の共有、プッシュ通知などと一緒に高速再開を使用するという前述の問題に注意したいと思います。 結局のところ、問題はありません。 ほとんどありません。 ユーザーが自分の電話を更新した場合(WP8 Update 3)、新しい更新でUrlへの移行に問題はありません。 しかし、 texnedoの同僚は、 AppResumeのバグが観察される興味深いシナリオを示しました。 アプリにアプリの再開が含まれていて、アプリケーションを最小化せずに画面をロックしている場合、トーストURLを使用せずにアプリケーションが単純に復元されます。



App Resumeとは何ですか?



アプリケーション実行の古典的なモデルでは、タイルをクリックすると(デスクトップ上またはアプリケーションリストをクリックしたときに)、起動するだけでなく、アプリケーションが起動および最小化されている場合は再起動します。 場合によっては、アプリケーションを再起動せずに、「戻る」ボタンをクリックしてユーザーが戻ってきたかのように、既に実行中のアプリケーションに戻る方が簡単です。 「重い」アプリケーションの場合、実行中のアプリケーションに再起動してデータを再初期化するよりも、実行中のアプリケーションに戻る方がはるかに速く、主観的に「起動」時間を短縮します。



Fast Application Switchの場合のように(App Resumeとは異なり、「戻る」ボタンを最小化した後、実行中のアプリケーションにすばやく戻るこの機能)、App ResumeはTombstoneの代わりではないため、アプリケーションが「スリープ」した場合、考慮する必要があることを考慮する必要がありますデータを完全に保存し、自分で復元します。



次に、この機能をアプリケーションに統合する方法を検討し、さまざまな返品シナリオを検討します。



アプリの再開を有効にする方法



この機能の有効化は非常に簡単です。必要なのは、XML編集モードでWMAppManifest.xmlファイルを開き(コンテキストメニュー-開く-Xmlエディター)、属性を追加するだけです。

ActivationPolicy="Resume"
      
      





<DefaultTask />







最終的に、マニフェストのデフォルト行は次のとおりです。

 <DefaultTask Name ="_default" NavigationPage="MainPage.xaml" />
      
      





次のようになります。

 <DefaultTask Name ="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>
      
      







アプリ再開の仕組み



App Resumeの作業の詳細を示すために、2つのページ間をナビゲートする機能を備えたシンプルなアプリケーションを作成します。 また、両方のページで、ボタンで変更できる変数の値を表示し、アプリケーションが起動されたかアクティブ化されたかなどのナビゲーション履歴を表示します。



簡単にするために、変数の値は静的フィールドの静的クラスのメモリに格納され、OnNavigateToの両方のページに表示されます



 static class FakeCacheStorage { public static int Counter { get; set; } }
      
      







App Resumeの動作を正確に把握するには、一時的に次の行をコメントアウトする必要があります。

RootFrame.Navigated + = CheckForResetNavigation;

App.xaml.csでは、コードはハンドラーに保存されます。



まず、Fast Application Switchingをチェックしてください。 アプリケーションを起動し、カウンターをある数(4にします)に増やして、アプリケーションを最小化して「戻る」ボタンに戻る前に何があるかを確認します







予想通り、全体の違いはアプリケーションの起動方法にあります。 最初に、アプリケーションが起動され、[戻る]ボタンでアクティブになりました。



次に、アプリケーションを最小化し、[戻る]ボタンの代わりにメインアプリケーションタイルからアプリケーションを起動した場合にどうなるかを見てみましょう。







ご覧のとおり、アプリケーションは起動されましたが、アクティブ化されておらず、メインページにありました。 さらに、変数の値がリセットされました。 明示的に、ストレージからすべてのユーザーデータを復元する必要があります。



そして今、マニフェストにApp Resumeを含めると、最終的には別の画像が表示されます。







しかし、これはすでに興味深いものです。メインページにアクセスし、カウンターの値が保存されている間に、アプリケーションはアクティブになりましたが、起動しませんでした。 「戻る」ボタンをクリックした場合にのみ、2番目のページが表示されます。 ナビゲーション履歴を表示しなかった場合、アプリケーションは単に再起動されたと考えられます。 最も興味深いことは、ユーザーが「戻る」ボタンを使用してアプリケーションを終了しようとしたときに始まります。このため、このボタンを3回押す必要があります。 次に、このためにApp Resumeが作成された理由と、この動作を使用するために使用できるシナリオを見ていきます。



アプリケーションをすばやく起動する方法としてのApp Resume



前のセクションで見たものは、思考のための興味深い食べ物を提供します。 App Resumeを使用して、すべてのデータをメモリに読み込んでアプリケーションをすばやく起動できますが、古いナビゲーション履歴を削除する必要があります。 つまり、実際には、ユーザーは「戻る」ボタンをクリックしてアプリケーションを終了する必要があります。 バージョンVS2012以降のスタジオでWP8アプリケーションを作成している場合、必要なメソッドは生成されたプロジェクトに既に追加されています。 App Resumeの操作を確認するために、App Resumeハンドラーの行を一時的にコメントアウトしました。

RootFrame.Navigated + = CheckForResetNavigation;



この行のコメントを解除すると、ナビゲーションの履歴は表示されなくなります。







実際、アプリケーションが起動されたように見えます(ユーザーはメインページに移動し、[戻る]ボタンを使用してアプリケーションを終了します)が、同時にデータはメモリに残ります。



このメソッドで何が実行されるかをさらに詳しく考えてみましょう。



InitializePhoneApplicationメソッド(app.xaml.csファイル)には、Navigatedイベントへの個別のサブスクリプションがあります。

RootFrame.Navigated + = CheckForResetNavigation;



ナビゲーション履歴は、Reset引数によって削除されます。



 private void CheckForResetNavigation(object sender, NavigationEventArgs e) { // If the app has received a 'reset' navigation, then we need to check // on the next navigation to see if the page stack should be reset if (e.NavigationMode == NavigationMode.Reset) RootFrame.Navigated += ClearBackStackAfterReset; }
      
      







それに応じて、ClearBackStackAfterResetメソッドでさらにナビゲーション履歴がクリアされます。



 private void ClearBackStackAfterReset(object sender, NavigationEventArgs e) { // Unregister the event so it doesn't get called again RootFrame.Navigated -= ClearBackStackAfterReset; // Only clear the stack for 'new' (forward) and 'refresh' navigations if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh) return; // For UI consistency, clear the entire page stack while (RootFrame.RemoveBackEntry() != null) { ; // do nothing } }
      
      







ここで新規および更新のサブスクリプションがあるのはなぜですか? 例を見てみましょう。



2番目のページでApp Resumeを使用すると、ページのOnNavigateToメソッドにブレークポイントを作成して、ページがNewパラメーターで始まることを確認できます。 ただし、アプリケーションを最小化するときにすでにメインページにいた場合は、ナビゲーションパラメーターResetを使用してメインページに戻り、その後このメソッドで処理されるナビゲーションパラメーターRefreshを使用します。



次に、App Resumeを使用するための別の興味深いシナリオを検討します。アプリケーションを起動せず、それに戻る場合です。



実行中のアプリケーションに戻るには、アプリの再開。 「iOSまたはWP8.1のように」



うわさによると、メインタイルによってWP8.1の下にあるアプリケーションはデフォルトでは再起動されず、復元されます。 これがそうであるかどうかに関係なく、私たちはビルド後にのみ見つけることができます。 それまでの間、「iOSのような」動作を行うことができます。つまり、ユーザーがアプリケーションを最小化してメインタイルをクリックすると、それがあった同じページに移動し、アプリケーションは再起動しません。 この機能は「iOSのように」するためではなく、使いやすく便利で高品質なアプリケーションを作成するために使用する必要があることを理解することが重要です。 そして一般的に、WPユーザーは、メインタイルをクリックするとアプリケーションが再起動する可能性が高いという事実に慣れています。

実際、ユーザーは画面にナビゲーション履歴とユーザーデータを保存しながら、単に「戻る」ボタンを使用してアプリケーションに切り替えた場合と同じ方法でアプリケーションにアクセスする必要があります。



ふるまいの2つの主なシナリオを処理する必要があります。

1.ユーザーがアプリケーションタイルをクリックします。

2.ユーザーはリンク(プッシュ通知、セカンダリタイル、写真共有など)を介してアプリケーションをアクティブにします。



最初の場合、このシナリオを実装するには、まず、アプリの再開時に履歴リセットをオフにします。

App.xaml.csでは、 NavigatedのサブスクリプションとCheckForResetNavigationメソッドを削除し、 Navigatingイベントにサブスクライブします(ページに移動する前に発生し、移行をキャンセルできます)。

RootFrame.Navigating + = ContinueExecution;



アプリケーションが起動すると、メソッドで、最初にイベントがReset引数を受け取り、次にアプリケーションタイルをクリックしたときにNew引数を含むイベントが来ることがわかります。



この動作を考慮して、ContinueExecutionの実装を詳しく見ていきます。



 private bool isRelaunch = false; private void ContinueExecution(object sender, NavigatingCancelEventArgs e) { if (e.NavigationMode == NavigationMode.Reset || (isRelaunch && e.NavigationMode==NavigationMode.New)) { if (isRelaunch && e.Uri.OriginalString != "/MainPage.xaml") { RootFrame.Navigated+=ClearBackStackAfterReset; return; } e.Cancel = true; isRelaunch = !isRelaunch; } }
      
      







ClearBackStackAfterResetメソッドは、新しいWP8プロジェクト用にスタジオによって生成され、ナビゲーション履歴を単純にクリアします。



 private void ClearBackStackAfterReset(object sender, NavigationEventArgs e) { RootFrame.Navigated -= ClearBackStackAfterReset; if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh) return; while (RootFrame.RemoveBackEntry() != null) { } }
      
      







ここでわかるように、チェック条件がスタートページに追加されています。

 if (isRelaunch && e.Uri.OriginalString != "/MainPage.xaml")
      
      







最小化されたアプリケーションがセカンダリタイル、プッシュ通知などによってアクティブ化される2番目のシナリオでは、検証が必要です。

この場合、履歴は消去され、アプリケーションをアクティブにしてユーザー履歴を処理した後、「戻る」ボタンを使用してアプリケーションを終了します。



たとえば、プッシュ通知で、履歴を削除するのではなく、アプリケーションの使用を継続する場合は、行を削除するだけです

RootFrame.Navigated + = ClearBackStackAfterReset;

または、プッシュ通知を使用してリンクの条件をもう1つ追加します。



2番目のシナリオの動作を示すために、次のページにボタンを追加して2番目のリンクを生成します。



 <Button Content="Secondary Tile" Click="ButtonTile_OnClick"></Button>
      
      







このボタンにかなり単純なハンドラーを追加します。



 private void ButtonTile_OnClick(object sender, RoutedEventArgs e) { var secondTile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("issecondtile")); if (secondTile == null) { var newTileData = new StandardTileData { Title = "Second Page", }; ShellTile.Create(new Uri("/SecondPage.xaml?id=someid&issecondtile=true", UriKind.Relative), newTileData); } }
      
      







ここで、アプリケーションを起動すると、2ページ目に移動します。 その後、タイルをクリックすると、アプリケーションがナビゲーション履歴なしで起動し、同時にメインタイルのナビゲーション履歴から起動することがわかります。







まとめ



App Resumeのシンプルさにもかかわらず、仕事の原則の説明は非常に膨大であることが判明しました。 ご覧のとおり、App Resumeを使用すると、アプリケーションの起動を高速化できるだけでなく、アプリケーションの動作を「iOSのように」することができます。 また、タイル回復アプリケーションスクリプトで廃棄(Tombstone)を忘れないことが特に重要です。 この場合、ナビゲーションの履歴全体を保存しますが、同時にメモリ内のすべてのユーザーデータが破壊されるため、ストレージから画面上でそれらを復元する必要があります。



All Articles