TimerTask + BlockingQueue を AsyncTask で!

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();
}