- 2012-05-16 (水) 22:10
- Android
時間経過や一定間隔での処理を行う場合にはタイマーがよく使われます。
今回はタイマーの基本的な使い方をまとめてみました。
タイマー機能はTimerクラスおよびTimerTaskクラスにまとめられています。
大まかな処理の流れは次のようになります。
- Timerオブジェクト作成
- Timerクラスの schedule() もしくは scheduleAtFixedRate() でタイマー起動
- Timerクラスの cancel() でタイマー停止&破棄
Timerオブジェクト作成
Timerクラスにはいくつかのコンストラクタが定義されています。
メソッド | 説明 |
---|---|
Timer() | ユーザースレッドで動くタイマーオブジェクトを作成する。 |
Timer(boolean isDaemon) | 指定されたスレッド種別で動くタイマーオブジェクトを作成する。 |
Timer(String name) | 名前付きユーザースレッドで動くタイマーオブジェクトを作成する。 |
Timer(String name, boolean isDaemon) | 指定された種別の名前付きスレッドで動くタイマーオブジェクトを作成する。 |
isDaemon という引数を取るコンストラクタがありますが、これはスレッド種別を指定するものです。
この辺りはスレッドに関する知識が必要になってきますので、簡単に説明しておきます。
スレッドには「ユーザスレッド」と「デーモンスレッド」というものが存在します。
ユーザスレッドとは、ユーザプロセス環境で実行されるスレッドのことをいいます。
このスレッドはプログラム終了時などに実行中の処理があった場合に、その処理の終了を待ちます。つまり、全ての実行中処理が終了してからスレッドが破棄されることになります。
一方のデーモンスレッドですが、こちらはプログラムの実行終了を待たないで終了することができるスレッドです。デーモンスレッドが実行中でもプログラム(ユーザスレッド)が終了してしまえば、デーモンスレッドは強制的に終了されます。
タイマー起動
schedule() および scheduleAtFixedRate() でタイマーのスケジューリングを行います。これらのメソッドは次のように定義されています。
メソッド | 説明 |
---|---|
schedule(TimerTask task, long delay) | [delay]ms後に1度だけタスクが実行される。 |
schedule(TimerTask task, long delay, long period) | [delay]ms後にタスクが実行され、それ以降はタイマーが停止されるまで[period]ms間隔でタスクが実行され続ける。 |
schedule(TimerTask task, Date when) | [when]で指定した日時に1度だけタスクが実行される。 |
schedule(TimerTask task, Date when, long period) | [when]で指定した日時にタスクが実行され、それ以降はタイマーが停止されるまで[period]ms間隔でタスクが実行され続ける。 |
scheduleAtFixedRate(TimerTask task, long delay, long period) | [delay]ms後にタスクが実行され、それ以降はタイマーが停止されるまで[period]ms間隔でタスクが実行され続ける。 |
scheduleAtFixedRate(TimerTask task, Date when, long period) | [when]で指定した日時にタスクが実行され、それ以降はタイマーが停止されるまで[period]ms間隔でタスクが実行され続ける。 |
[task]にはタスク処理を実装したTimerTaskオブジェクトを指定します。
タスク処理をTimerTaskクラスの run() の中に記述しておけば、上記メソッドで指定したタイミングでこの処理が呼び出されます。
schedule() と scheduleAtFixedRate()
schedule() と scheduleAtFixedRate() という2つのメソッドがありますが、これらの違いは次の通りです。
- schedule() は、実際のタスクの開始時刻を基準として、それからperiod[ms]後に次のタスクを実行するよう設定する
- scheduleAtFixedRate() は、最初に実行したタスクの開始時刻を基準として、n回目に実行されるタスクを(period × n)[ms]後に実行するよう設定する
schedule() は相対時間によるスケジューリングを行っているため、何らかの理由で処理に遅延が生じた場合は以降の処理が呼び出されるタイミングにも影響を及ぼします。
それに対して scheduleAtFixedRate() は絶対時間によるスケジューリングを行っており最初のタスク実行時間を基準としているため、どこかで処理に遅延が生じてもそれ以降の処理が呼び出されるタイミングに影響を及ぼすことはありません。
より正確な定期処理を必要とされる場面(時計の実装など)では scheduleAtFixedRate() を使うことをお勧めします。
タイマー停止
タイマーの停止には cancel() を使用します。
また、タスクキューから不要なタスクを削除したい場合は purge() を使います。cancel() によるキャンセル処理が大量に出てくる可能性がある場合は呼び出しておいた方がいいでしょう。
なお、TimerオブジェクトやTimerTaskオブジェクトは一度 cancel() を呼び出すとリソースが破棄されてしまい再利用できません。
再度タイマーを使う場合はTimerオブジェクトを作り直さなければなりませんので注意してください。
サンプルコード
タイマーを使ったサンプルです。
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_Root" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="#FF0000" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" > <Button android:id="@+id/btn_Start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start" /> <Button android:id="@+id/btn_Stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Stop" /> </LinearLayout> </LinearLayout>
TimerTestActivity.java
public class TimerTestActivity extends Activity { int red = 0; LinearLayout llRoot; Button btnStart; Button btnStop; Timer timer = null; Handler handler = new Handler(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //==== コントロール取得 ====// llRoot = (LinearLayout)findViewById(R.id.ll_Root); btnStart = (Button)findViewById(R.id.btn_Start); btnStop = (Button)findViewById(R.id.btn_Stop); //==== リスナー設定 ====// btnStart.setOnClickListener(new OnClickListener() { public void onClick(View v) { if(timer == null) { //==== タイマー作成 & スタート ====// timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { handler.post(new Runnable() { public void run() { red++; if(0xFF < red) { red = 0; } llRoot.setBackgroundColor(Color.rgb(red, 0, 0)); } }); } }, 0, 10); } } }); btnStop.setOnClickListener(new OnClickListener() { public void onClick(View v) { if(timer != null) { timer.cancel(); timer.purge(); timer = null; } } }); } }
Startボタンが押下されるとタイマーを起動し、背景色を徐々に赤くするようにしています。
Stopボタンを押下されるとタイマーを停止します。
関連があると思われる記事:
- [Android] マルチスレッド(その1)
- [Android] Fix Project Properties.
- [Android] Spinnerの基本的な使い方
- [Android] ScrollViewのスクロールいろいろ
- [WPF] DataGridのスクロール制御
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://gacken.com/wp/program/android/1210/trackback/
- Listed below are links to weblogs that reference
- [Android] タイマーの使い方 from ミライニトドケ