2016-03-27 65 views
1

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

这是我的代码:

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

而且,不能正常工作。

+0

的http://计算器。com/questions/7882739/android-setting-a-timeout-for-an-asynctask – Manifest

回答

1

我认为你可以使用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); 
+0

我已根据您的答案编辑代码。我不知道,但不起作用。 @saran –

+0

@SamsulArifin你面临的错误/问题是什么? – sharan

+0

并创建一个单独的线程来运行n.get不要在主线程中运行这个... – sharan

0

你为什么要取消定时器?刚打电话schedule()

取消计时器,所有预定的任务

timer.cancel();应该被删除。检查docs取消()

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; 
} 
1

这是另一种方法。在您的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; 
} 

`

+0

然后,我可以把代码在超时时退出应用程序? –

+0

达到超时时,while循环将自动退出,'null'将从'doInBackground' methd返回,然后'onPostExecute'将被调用,并且您可以将代码放在那里。 –

+0

我也在尝试你的代码。我认为更高效和更有效。但是,我仍然混淆了在超时和不在onPostExeute之间检查。你有想法吗? –

0

只需改变你这样的代码,并检查您的异步任务是否得到取消与否。

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

,并在onCancelld方法写你的逻辑

@Override 
protected void onCancelled() { 
Log.d(TAG,"Asynctask has been cancelled."); 
} 
+0

我一直在尝试你的代码。所有的。然后,同样的结果。上面提到的问题是,当用户打开GPS,然后自动加载长时间和纬度。但有时,用户的互联网连接速度较慢,所以如果用户在1分钟后无法加载长时间宽度。这些应用程序将退出。 –

+0

提到的方法应该工作,除非你正在做一些不同的事情,因为它为我们工作! –

+0

感谢您的回答。我被找到了另一种方式。这个http://stackoverflow.com/questions/7882739/android-setting-a-timeout-for-an-asynctask 完美的工作。但是你的代码也可以用不同的方法工作。再次感谢 –