如何为AsyncTask执行设置超时?

时间:2016-03-27 09:22:06

标签: android android-asynctask

我一直试图在AsyncTask执行超过1分钟时创建超时。如果时间到了,那么应该退出通知。

这是我的代码:

private class GetLongLat extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        longlatDialog = new ProgressDialog(MainActivity.this);
        longlatDialog.setMessage("Fetching Data. Please wait..");
        longlatDialog.setCancelable(false);
        longlatDialog.show();

    }

    @Override
    protected Void doInBackground(Void... arg0) {

         GPSTracker gpsTracker;

         //This is the timer to set time out
         Timer timer = new Timer();
         timer.schedule(new TaskKiller(this), 3000);
         timer.cancel();

         do{
             gpsTracker = new GPSTracker(MainActivity.this);
             gpsTracker.getLocation();

         }while(!String.valueOf(gpsTracker.latitude).equals("0.0"));

        return null;
    }

    protected void onCancelled() {
     // do something, inform user etc.
        Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show();
        System.exit(1);
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        if (longlatDialog.isShowing())
            longlatDialog.dismiss();
    }

}

这是一个在doInBackground中调用的类来设置时间。

class TaskKiller extends TimerTask {
 private AsyncTask<?, ?, ?> mTask;

  public TaskKiller(AsyncTask<?, ?, ?> task) {
    this.mTask = task;
  }

  public void run() {
     mTask.cancel(true);
  }
}

但是当我运行代码时,没有任何事情发生。我的意思是进度对话框总是运行很长时间。

修改 我编辑了我的代码来调用这样的GetLongLat:

GetLongLat n = new GetLongLat();
n.execute();
try {

    n.get(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (ExecutionException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (TimeoutException e) {
    // TODO Auto-generated catch block
    Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show();
    System.exit(1);
} 

但是,也没有用。

5 个答案:

答案 0 :(得分:2)

我认为你可以使用AsyncTask.get()

GetLongLat n = new GetLongLat();
n.get(30000, TimeUnit.MILLISECONDS);

你必须在一个单独的线程中使用n.get。

编辑:一种不同的方法,但效率不高。

GetLongLat n = new GetLongLat();
n.execute(); 
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
   @Override
   public void run() {
       if ( n.getStatus() == AsyncTask.Status.RUNNING )
           n.cancel(true);
  }
 }, 30000 );

答案 1 :(得分:0)

你为什么要取消计时器?在致电schedule()之后?

  

取消计时器和所有计划任务

应删除

timer.cancel();。检查docs是否取消()

答案 2 :(得分:0)

您可以通过多种方式实现此行为。

以下是使用CountDownTimer

的示例
// Start your AsyncTask
private YourAsyncTask mTask = new YourAsyncTask().execute();

// Run a timer after you started the AsyncTask
new CountDownTimer(60000, 1000) {

    public void onTick(long millisUntilFinished) {
        // Do nothing
    }

    public void onFinish() {
        mTask.cancel(true);
    }

}.start();

您正在启动计时器后取消计时器。你也可以这样做。但是根本不建议这种忙碌的等待。

@Override
protected Void doInBackground(Void... arg0) {

     GPSTracker gpsTracker;

     //This is the timer to set time out
     new CountDownTimer(60000, 1000) {

         public void onTick(long millisUntilFinished) {
             // Do nothing
         }

         public void onFinish() {
             // Set latitude to zero to finish the while loop outside.
             // gpsTracker.latitude = "0.0"; // Something like this
         }

     }.start();

     do{
         gpsTracker = new GPSTracker(MainActivity.this);
         gpsTracker.getLocation();

     }while(!String.valueOf(gpsTracker.latitude).equals("0.0"));

    return null;
}

答案 3 :(得分:0)

这是另一种方法。在doInBackground方法中,您可以使用System.currentTimeMillis检查是否已过去1分钟。

protected Void doInBackground(Void... arg0) {

         GPSTracker gpsTracker;

         long startTime = System.currentTimeMillis();

         do{
             gpsTracker = new GPSTracker(MainActivity.this);
             gpsTracker.getLocation();

         }while(!String.valueOf(gpsTracker.latitude).equals("0.0")
                && ((System.currentTimeMillis() - startTime) <= 60000);//60000 millisecond = 1 minute

        return null;
}

`

答案 4 :(得分:0)

只需改变您的代码,检查您的异步任务是否被取消。

mongod.exe --storageEngine=mmapv1

并在onCancelld方法中编写逻辑

            GetLongLat getLongLatAsync = new GetLongLat();
            getLongLatAsync.execute();
            try {
            Handler handler = new Handler();
            /** 1st method **/
            handler.postDelayed(new Runnable()
             {
              @Override
              public void run() {
                 if (getLongLatAsync.getStatus() == AsyncTask.Status.RUNNING )
                  getLongLatAsync.cancel(true);
                }
              }, 3000 ); //3 Seconds
    /** 1st method ends **/
    /** second method */
            handler.post(new Runnable()
             {
              @Override
              public void run() {
        getLongLatAsync.get(3000, TimeUnit.MILLISECONDS);//You should run it in seperated thread or else it will block ui thread.
    }
    });
/** Second method ends**/
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (TimeoutException e) {
                // TODO Auto-generated catch block
                Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show();
            }