Android + Java で、TimerTask クラスを使った、ストップウォッチアプリを作ります。
Java でタイマー処理を実装する場合は、Timer クラスで処理を行う間隔(スケジュール)を指定し、その間隔ごとに TimerTask クラスで指定した処理を実行します。
完成イメージ
この記事で作成するストップウォッチアプリの完成イメージは次のとおりです。
今回はシンプルに、ストップウォッチの時間を表示する TextView と、タイマーを開始・停止するボタンがあるだけの簡単なアプリを作ります。
プロジェクトの作成
まだ、Android Studio をインストールしていない場合は、次の記事でインストール方法を解説していますので、そちらをご覧ください。
【関連記事】
▶Javaで簡単なAndroidゲームアプリを開発(環境準備)
Android Studio を起動したら、新規プロジェクトの作成から「空のアクティビティ」を選択します。
アプリ名(名前)、パッケージ名、保存先には任意の値を設定します。言語は今回 Java を選択します。
レイアウトの作成
最初に、アプリの見た目の部分となるレイアウトを作成します。
プロジェクトツリーから activity_main.xml 選択し、レイアウトエディタを開きます。
完成イメージのとおりコンポーネントを配置していきます。
まず、LinearLayout をルートに配置して、時間を表示する TextView と開始・停止を行う Button 2つを配置します。
レイアウトの XML は次のようになります。デザイナでコンポーネントを貼り付けるのが面倒な場合は、この XML をエディタに貼り付ければ画面デザインが完成します。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/txtTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00:00.000"
android:textSize="40dp"
android:layout_marginBottom="20dp"/>
<Button
android:id="@+id/btnStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="START" />
<Button
android:id="@+id/btnStop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="STOP" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
TimerTask でストップウォッチを実装
次はストップウォッチの中のロジックをつくっていきます。
まず Start ボタンが押された時の処理を実装します。Start ボタンが押されたら、Timeer および TimerTask クラスを使用して、一定間隔ごとにコールバックを発生させ、ストップウォッチの時間を更新していきます。
MainActivity.java 開いて、次のクラス変数および onClickStart メソッドを追加します。
private Timer timer;
LocalTime time;
// Start が押された時のイベント
@RequiresApi(api = Build.VERSION_CODES.O)
public void onClickStart(View view) {
//既に Start ボタンが押されてタイマーが起動中の場合
if (timer != null) {
return;
}
TextView textViewJudge = (TextView)findViewById(R.id.txtTime);
final Handler handler = new Handler();
//ストップウォッチの時間をリセット
time = LocalTime.of(0, 0);
//100msec ごとに画面を更新する
int period = 100;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//ストップウォッチの時間に 100msec 加算
time = time.plusNanos((long) (period * Math.pow(10, 6)));
//UIの更新はメインスレッドで行う必要があるため、Handlerを使用する
handler.post(new Runnable() {
@Override
public void run() {
//画面に現在の経過時間を表示
String fmt = time.format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS"));
textViewJudge.setText(fmt);
}
});
}
}, 0, period);
}
一定間隔で、決められた処理を繰り返し実行したいならば、Timerクラス(java.utilパッケージ)のscheduleAtFixedRateメソッドを利用します。引数には、実行すべき処理(TimerTaskオブジェクト)、開始時刻(ミリ秒)、実行スパン(ミリ秒)の順で指定します。
次に、Stop ボタンが押された時の停止処理を実装します。
Stop ボタンが押された時に、Timer クラスの cance メソッドを呼び出し、タイマーを停止します。
// Stop が押された時のイベント
public void onClickStop(View view) {
if(null != timer){
// Cancel
timer.cancel();
timer = null;
}
}
ボタンのイベントと Javaメソッドの紐付け
最後は、Start と Stop ボタンが押された時に、Javaの onClickStart と onClickStop メソッドが実行されるように紐付けを行います。
再び、 activity_main.xml をレイアウトエディタで開きます。
Start ボタンを選択し、画面右の属性の onClick にonClickStart を選択します。
Stop ボタンも同様に選択し、onClick 属性にonClickStop を選択します。
これで、ストップウォッチアプリの完成です。エミュレーターまたは実機で実行し、正常に動作するか確かめてみましょう。
まとめ
今回は、Timer および TimerTask クラスを使って、ストップウォッチの Android アプリを作ってきました。Android アプリに限らず、Timer クラスを使えば、一定間隔ごとの処理を簡単に実装することができます。
Timerクラスには、一定間隔で決められた処理を実行するメソッドとして schedule と scheduleAtFixedRate の2つが用意されています。schedule は前回の開始時間から period で指定された時間を経過したタイミングで次の処理が実行されるのに対し、scheduleAtFixedRate は、初回の開始時間から period の間隔ごとに処理が呼び出されます。また、どちらの処理もタスクの実行予定時間なっても前のタスクが終了していない場合は、前のタスクが終了するまで実行が待機されます。