日の終わりに今日のまとめ

開発や仕事で使った技術をまとめてます。

[android]Timer、TimerTask処理の停止を実装しよう[java]

 

[android]Timer、TimerTask処理を使って画面の描画処理[java] - 日の終わりに今日のまとめ

前回はTimer、TimerTask処理を使って非同期での処理について書きました。

今回はその発展で処理の停止機能を付与します。

 

 

MainTimerActivity.java 

package com.example.test;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainTimerActivity extends Activity {

	Handler m_handler = null;
	TextView m_timerCount = null;
	Button m_stopButton = null;
	Timer m_timer = null;
	MyTimerTask m_timerTask = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		m_handler = new Handler();
		setContentView(R.layout.activity_timer);
		m_timerCount = (TextView) findViewById(R.id.timerCount);
		//タイマーストップボタン
		m_stopButton = (Button)findViewById(R.id.stopButton);
		m_stopButton.setOnClickListener(new StopClickListener());

		Timer timer = new Timer();
		m_timerTask = new MyTimerTask();
		timer.schedule(m_timerTask, 0, 5000); // 即座にタイマー処理を実行する,5秒間隔で処理を繰り返し起動する
	}
	
	// タイマーストップボタン押下時の処理
	class StopClickListener implements OnClickListener{
		public void onClick(View v){
			m_timer.cancel();
		}
	}

	class MyTimerTask extends TimerTask {

		int timerCnt = 1;
		
		@Override
		public void run() {
			while (true) {
				timerCnt++;
				// Viewの操作には更に別スレッドで実行させる
				m_handler.post(new Runnable() {
					@Override
					public void run() {
						m_timerCount.setText(String.valueOf(timerCnt));
					}
				});
				
				if((timerCnt % 10000) == 0)
					break;
			}
		}
	}

}

 

 

activity_timer.xml 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/timerCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    
    <Button
        android:id="@+id/stopButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/timerCount"
        android:text="タイマーストップ" />

</RelativeLayout>

 

 注意点として、Timer.cancel();は実行中のタイマー処理を即座に終了させるのではなく、

終了できるタイミングまで処理を行い、以降処理の再開を行わないようにするメソッドです。

上記のプログラムであれば、キャンセルしたタイミングのタイマーを最後まで実行し、

5秒後のタイマーの再起動はされず、必ず10000の倍数でカウントが止まるはずです。

 

タイマーの処理を即座にストップさせたい処理は以下のように書くことも出来ます 。 

 

MainTimerActivity2.java 

package com.example.test;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainTimerActivity2 extends Activity {

	Handler m_handler = null;
	TextView m_timerCount = null;
	Button m_stopButton = null;
	MyTimerTask m_timerTask = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		m_handler = new Handler();
		setContentView(R.layout.activity_main);
		m_timerCount = (TextView) findViewById(R.id.timerCount);
		//タイマーストップボタン
		m_stopButton = (Button)findViewById(R.id.stopButton);
		m_stopButton.setOnClickListener(new StopClickListener());

		Timer timer = new Timer();
		m_timerTask = new MyTimerTask();
		timer.schedule(m_timerTask, 0); // 即座にタイマー処理を実行する
	}
	
	// タイマーストップボタン押下時の処理
	class StopClickListener implements OnClickListener{
		public void onClick(View v){
			m_timerTask.setEnd();
		}
	}

	class MyTimerTask extends TimerTask {

		int timerCnt = 1;
		boolean endFlg = false;
		
		// 終了設定を行います
		public void setEnd(){
			endFlg = true;
		}

		@Override
		public void run() {
			while(!endFlg){ // 終了設定がされるまで繰り返す
				timerCnt++;
				// Viewの操作には更に別スレッドで実行させる
				m_handler.post(new Runnable() {
					@Override
					public void run() {
						m_timerCount.setText(String.valueOf(timerCnt));
					}
				});
			}
		}
	}

}