Android の UI スレッドで TimerTask を裸で使うと失敗する。
そこで、TimerTask と java1.5 からの BlockingQueue を、AsyncTask で実装してやると、かなり汎用的になる。
AsyncTask を以下のように実装する。
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import android.os.AsyncTask;
/**
* TimeUpTask
*/
public abstract class TimeUpTask extends AsyncTask<Integer,Void,Boolean>{
private Timer timer;
BlockingQueue<Boolean> que;
// alertShow(true) でタイムアウトの処理をさせる
public abstract void alertShow(boolean timeout);
@Override
protected void onPreExecute(){
que = new ArrayBlockingQueue<Boolean>(8);
}
/**
* params[0] = 秒数
*/
@Override
protected Boolean doInBackground(Integer...params){
timer = new Timer();
timer.schedule(new TimerTask(){
@Override
public void run(){
que.add(new Boolean(true));
}
},params[0] * 1000);
try{
Boolean rtn = que.take();
return rtn;
}catch(InterruptedException e){
que.add(new Boolean(false));
}
}
@Override
protected void onPostExecute(Boolean result){
alertShow(result);
}
@Override
protected void onCancelled(){
if (timer != null) timer.cancel();
que.add(new Boolean(false));
}
}
これの呼び出し、、、
TimeUpTask timeupTask;
タイマーセット....
timeupTask = new TimeUpTask(){
@Override
public void alertShow(boolean res){
if (res) forceFinish(); // 外に宣言するダイアログ表示を実行
}
};
timeupTask.execute(20);
タイマーキャンセル...
if (timeupTask != null){
timeupTask.cancel(false);
}
-----------------------
protected void forceFinish(){
webview.clearView();
new AlertDialog.Builder(this)
.setMessage("タイムアウト強制終了")
.setCancelable(false)
.setPositiveButton("OK",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog,int which){
// TODO Activity 終了の為に必要な処理を実行
finish();
}
}).create().show();
}