このページの本文へ

前へ 1 2 次へ

これで作れる! Androidのアプリケーション 第10回

ブロードキャストへの応答とタイマ割り込み

2010年09月09日 12時00分更新

文● 塩田紳二

  • この記事をはてなブックマークに追加
  • 本文印刷

タイマー割り込みを使う

 もう1つ、毎秒ごとに画面を更新させる部分を解説しておきましょう。以前解説したように(関連記事)アプリケーションはActivityでできており、Activityには、特定の状態遷移があります。アプリケーションが動作していても、他のアプリケーションが起動してバックグラウンドになることもあるし、メモリから追い出されてしまうこともあります。こうしたタイミングは、onResumeやonPauseで検出することができます。

 アプリケーションは、onCreateを実行したあと必ずonResumeを通り、画面が切り替わるときにはonPauseを通ります。このonResumeとonPauseは、他の場合にも通るルートなので、この2ヵ所でアプリケーションがフォアグランドなのかそうでないのかを検出することができるわけです。「世界時計サンプル」は時計なので、表示されている間は更新され続ける必要がありますが、バックグラウンドになっている間は動く必要(表示を変える)はありません。そこで、onResumeでタイマーをオンにして、一定期間ごとに画面を更新するようにして、onPauseでこれを止めるようにします。

サンプルの世界時計アプリでは、表示されていない状態では当然画面を更新する必要がないので、画面を復帰するonResumeのタイミングでタイマーをオンにすればいい

 Javaでは、タイマーによる周期的な実行にTimerオブジェクトを使います。このTimerオブジェクト自体は、Javaの標準オブジェクトなので、Androidとは無関係ですが、Androidアプリケーション内にあるメソッドを実行させるためには、ちょっとした仕組みが必要です。というのはAndroidでは、画面更新などはアプリケーションのコードが止まっている間に動くようになっているからです。たとえば、Toastの出力のあとにコードを実行させると、Toastが表示されなくなってしまいます。また、第8回で解説したProgressDialogでも別スレッドを作ったのは(関連記事)、アプリケーションのスレッドと切り替えて動作するGUIスレッドのためです。

 このときに使うのがHnadlerで、これはGUI側のスレッドが管理するキューに、処理したいオブジェクトを入れ、GUI側が順番にキューにあるオブジェクトを実行するという仕組みです。では細かくみていくことにしましょう。まずはonResumeです。ここは、どのような場合でも、アプリケーションが起動または再開するときに必ず通るメソッドです。WorldClock.javaでは、327行目からになります。

@Override
protected void onResume() {
  super.onResume();
  timer = new Timer(true);
  timer.schedule(
    new TimerTask(){
      public void run(){
        handler.post(new Runnable(){
          public void run(){ refresh(); }
        });
      }
    }
  , 1000, 1000);
}

 まず、Timerオブジェクトを作り、そこにscheduleメソッドで、TimerTaskを登録します。scheduleメソッドは、

public void schedule (TimerTask task, long delay, long period)

となっており、3つの引数のうち、最初が実行すべきTimerTask、次が遅延(最初の実行までの待ち時間)、最後がくり返し周期です。ここでは、遅延とくり返し周期に1000を指定してあり、単位はミリ秒なので1秒となっています。時計なので、本来なら最初の遅延は、現在のミリ秒を取得して零秒ぴったりに合わせる必要があるのですが、1秒以下の誤差はいいだろうということで初期値はそのままにしてあります。

 TimerTaskオブジェクトは、コードにあるようにここで生成されています。TimerTaskオブジェクトはrunメソッドがあり、Timerから実行されるときには、このメソッドが呼び出されます。

 このrunメソッドの中にあるのが、postメソッドです。handler自体は、worldclcokアクティビティのプライベート変数として先頭付近で定義されています。

 postメソッドは、Runnableオブジェクトを引数とします。やはりRunnableオブジェクトも内部にあるrunメソッドに実行したい処理を記述します。

 オブジェクトがネストしていますが、Handlerにポストされる処理は、refreshメソッドの呼び出しだけです。HanderをTimeTask内で直接書かないだけでやっていることは単純です。

 次に、アクティビティが停止または中断するときに通過するonPauseメソッドを見ます。これは、WorldClock.javaの320行目にあります。

@Override
protected void onPause() {
  super.onPause();
  timer.cancel();
  timer.purge();
}

 ここでやっているのは、タイマーを止めて、スケジュールされているタスクを取り消しています。その後、purgeでタスクキューからタスクを消去させています。purgeの説明では「Removes all canceled task from the task queue」となっているので、さきにcancelしておく必要があるようです。

 さて、これで、Android開発の大きなポイントは解説したので、次回は実際に作成したアプリをAndroidマーケットへ登録するまでを紹介する予定です。

前へ 1 2 次へ

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン