2011年4月23日土曜日

[Android] Activityに時計を表示する(Activityの非同期更新)

How to update Activities asynchronously

AndroidのActivityは別スレッドでの更新処理が禁止されています。
たとえば1秒ごとにActivityに現在時刻を表示するためにThread#runでループするような処理をするとエラーになります。
AsyncTaskクラスのonPreExecuteメソッドやonPostExecuteメソッドで1秒ごとにActivityの更新をするようなループはエラーにはなりませんがActivityが更新されないし、操作を受け付けなくなります。

Activityを非同期で更新するのにはHandlerクラスを使います。
HandlerクラスのActivityを更新するためのメソッドのうち、sendEmptyMessagepostを使ってみます。
sendEmptyMessageメソッドとpostメソッドの違いは引数だけです。ソースを見たところ内部的に同じ処理をしています。

1. handler#sendEmptyMessage
以下は1秒ごとにActivityに現在時刻を表示するHandlerクラスのsendEmptyMessageメソッドを使ったソースです。

マニフェスト(AndroidManifest.xml)
レイアウト(main.xml)
Activityのソース(Main.java)
これで無事に1秒ごとにActivityに現在時刻を表示できました。

sendEmptyMessageDelayedを使うべきところにsendMessageDelayedを使うと"This message is already in use."というエラーが起きるので注意が必要です。
※when=の後の数値は毎回異なるようです。

2. handler#post
次は1秒ごとにActivityに現在時刻を表示するHandlerクラスのpostメソッドを使ったソースです。
sendEmptyMessageメソッドの代わりにpostメソッド、sendEmptyMessageDelayedメソッドの代わりにpostDelayedメソッドを、removeMessagesメソッドの代わりにremoveCallbacksメソッドを使っています。

Activityのソース(Main.java)
マニフェスト(AndroidManifest.xml) と
レイアウト(main.xml) は同じ

postDelayedメソッドやpostメソッドはRunnableインターフェイスを引数に使うので継承次第では便利な使い方ができるかもしれません。


以上、参考になれば幸いです。

2 件のコメント:

  1. HandlerとRunnableで時刻の更新プログラムを組んでいて期待通り動かず困っていたところ、こちらのサイトに出会いとても助かりました。ありがとうございます。

    返信削除
    返信
    1. コメントありがとうございます。
      お役に立てて光栄です。

      削除