Windows Phone 7.1 ページ遷移とセンサー管理


Windows Phone 7.1のSilverlightアプリケーションはPage単位で作成されています。このポストではページの遷移とセンサーのライフサイクル管理を結びつける一例を解説します。

注意点でも説明したように、センサーを無駄に動かすと無駄に電池を消費するので、センサーのライフをきちんと管理しなければなりません。アプリケーションの設計上、センサー計測を止めるための何がしかのトリガーが入っているはずですが、例えば戻るボタンを押されればセンサーを使うロジックが含まれたページは消えて前に表示されていたページが表示されるので、戻るボタンが押されたタイミングでセンサーを停止する必要もあります。このことを考えると、センサーのライフサイクルの大枠の管理はページの遷移に紐付けておいたほうがすっきりするし、確実にセンサーのライフサイクル管理ができます。

ページの遷移は、ApplicationPageクラスを継承する各ページクラスのメソッドをオーバーライドすることによってハンドリングが可能です。

  • protected override void OnNavigateTo(System.Windows.Navigation.NavigationEventArgs e)
    対象ページが表示される時にコールされる
  • protected override void OnNavigateFrom(System.Windows.Navigation.NavigationEventArgs e)
    対象ページから別のページに遷移する時にコールされる

先ず、ページが表示されている間センサーインスタンスを保持するためのクラスメンバーをページクラスに追加します。

private Motion motion;

そして、対象ページが表示される時にコールされるOnNavigateToメソッドに以下のようなコードを書きます。

protected override void OnNavigateTo(System.Windows.Navigation.NavigationEventArgs e)
{
    if (Motion.IsSupported)
    {
        motion = new Motion();
        motion.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<MotionReading>(motion_CurrentValueChanged);
    }
}

ここで、センサーのインスタンスを作っておきます。これで、ページが表示された後に実行されるコードが動く時には、必ずセンサーインスタンスが存在していることになります。また、センサーはデバイスと一対一のものなので、インスタンスはただ一つだけあればよいので、これで十分です。それから計測データを非同期的に受け取るためのハンドラーもここで登録しておきます。そうしておけば、別の場所でStartをかけるだけで計測が開始されます。

次に、対象ページから別のページに遷移する際にコールされるOnNavigateFromには以下のようなコードを書きます。

protected override void OnNavigateFrom(System.Windows.Navigation.NavigationEventArgs e)
{
     if (motion != null)
    {
        motion.Stop();
       
        motion.Dispose();
    }
}

ここでは、センサーの計測停止と、リソースの解放処理を行います。センサークラスにはセンサーの状態を保持するプロパティは無く、計測中かどうかを判断することはできないので、念のためStop()をコールしています。もちろん、Stop()メソッドのコールは、ページ表示中ずっとセンサーを使い続けるアプリを除いては、本筋のロジックのほうできちんとコーディングすることを忘れないでください。
センサー4クラスは、IDisposableインターフェイスを実装しています。センサーに限らず、IDisposableインターフェイスを実装しているクラスは、システム内部でリソースを食っているものが多いので、Dispose()メソッドをコールして使い終わったらリソースを解放しておきましょう。

はい、これでおしまい。
こんな感じでプログラムを書いておけば、ページの表示開始・終了に合わせてセンサーの生成・消滅を行うことができます。

あとは、センサー計測を始めたい場所(ボタンクリックやタップなど)で、

    if (motion != null)
    {
        motion.Start();

などとやれば、計測開始です。

 

Comments (0)

Skip to main content