本日は HoloLens の調査枠です。
HoloLens アプリがサスペンド状態に移行するタイミングとそこから実行状態に戻るタイミングを検出します。
3Dアプリでのサスペンド
HoloLens で3Dアプリを終了する場合、ブルームジェスチャーでアプリを終了することができます。
しかし、実際にはこのとき、3Dアプリはサスペンド状態に移行しており、完全に終了していません。
メモリの開放などが行われておらず、再びアプリを起動すると前回の状態から続けて起動するような形になります。
アプリを完全に終了するには対象アプリのパネルを閉じる必要があります。
UWPアプリの状態遷移
UWPアプリのライフサイクルは以下のページに参考資料があります。
docs.microsoft.com
docs.microsoft.com
サスペンドの検出
このためアプリ側から見ると、終了通知が受け取れないままアプリが完全終了させられたり、突如、実行環境が変化するケースが発生します。
これらの状態遷移を3Dアプリ側で検出するには OnApplicationFocus(bool) または OnApplicationPause(bool) 関数が利用できます。
docs.unity3d.com
docs.unity3d.com
サスペンド移行時には OnApplicationFocus が False、OnApplicationPause が True を返します。
サスペンドからの復旧時には OnApplicationFocus が True、OnApplicationPause が False を返します。
実機での動作を確認する
実際に HoloLens での動作を確認してみます。
以下の記事を元にHoloLens(WindowsMR)プロジェクトを作成します。
bluebirdofoz.hatenablog.com
2019/4/24現在、MRTK 2017 の最新バージョンは 2017.4.3.0 です。
サンプルコード
OnApplicationFocus(bool) と OnApplicationPause(bool) 関数の結果を表示する以下のスクリプトを作成します。
・AppChecker.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AppChecker : MonoBehaviour { /// <summary> /// 出力用テキストフィールド /// </summary> private UnityEngine.UI.Text p_text; /// <summary> /// 起動時処理 /// </summary> private void Start() { // Textコンポーネントを取得 p_text = GetComponent<UnityEngine.UI.Text>(); if (p_text != null) p_text.text = ""; string text = "Start"; message(text); } /// <summary> /// フォーカスの検出 /// </summary> /// <param name="focus"></param> private void OnApplicationFocus(bool focus) { string text = "OnApplicationFocus:" + focus; message(text); } /// <summary> /// 一時停止の検出 /// </summary> /// <param name="pause"></param> private void OnApplicationPause(bool pause) { string text = "OnApplicationPause:" + pause; message(text); } /// <summary> /// メッセージ出力 /// </summary> /// <param name="text"></param> private void message(string text) { if (p_text != null) { // 発生時刻と共にテキストフィールドに文字を出力 p_text.text += text; p_text.text += System.DateTime.Now.ToString(" hh:mm:ss"); p_text.text += System.Environment.NewLine; } } }
作成したスクリプトを Text オブジェクトにアタッチします。
後は HoloLens 向けにプロジェクトをビルドしてインストールします。
UnityプロジェクトのビルドとHoloLensへのインストール手順については以下を参照してください。
bluebirdofoz.hatenablog.com
HoloLensでの動作確認
HoloLens 上で動作確認を行います。
アプリ起動後に一度ブルーム操作でアプリを閉じ、30秒ほど待って再びパネルからアプリを呼び出してみました。
サスペンドへの移行のタイミングと、復旧のタイミングでそれぞれの関数が呼ばれています。
参考ページ
2019/09/16追記
OnApplicationPause(bool) と OnApplicationFocus(bool) の使い分けについてです。
この2つの関数はアプリでバックグラウンド処理が走っていた場合、異なる動きをします。
例えば、以下のようなサスペンド時にアプリを完全終了するスクリプトを準備します。
・AppCondition.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AppCondition : MonoBehaviour { /// <summary> /// 起動時処理 /// </summary> void Start() { } /// <summary> /// 一時停止の検出 /// </summary> /// <param name="pause"></param> private void OnApplicationPause(bool pause) { Debug.Log("OnApplicationPause:" + pause); // 一時停止された場合はアプリを完全終了する if(pause) { #if WINDOWS_UWP Windows.ApplicationModel.Core.CoreApplication.Exit(); #else Application.Quit(); #endif } } /// <summary> /// フォーカスの検出 /// </summary> /// <param name="focus"></param> private void OnApplicationFocus(bool focus) { Debug.Log("OnApplicationFocus:" + focus); // フォーカスが失われた場合はアプリを完全終了する if(focus == false) { #if WINDOWS_UWP Windows.ApplicationModel.Core.CoreApplication.Exit(); #else Application.Quit(); #endif } } }
通常、アプリ起動中にHoloLensのブルーム操作を行うと、OnApplicationPause 側の処理でアプリが強制終了します。
一方で、UNETでのネット接続のようなバックグラウンド処理が走っていた場合、OnApplicationFocus 側の処理でアプリが強制終了します。
これはバックグラウンド処理が走っていた場合、ブルーム操作を行ってもアプリが一時停止せず、OnApplicationPause が実行されないためです。