Android - 使用Timer和TimerTask控制任务?

37

我目前正在尝试在我的Android应用程序中设置WiFi扫描,每30秒扫描一次WiFi接入点。

我使用了Timer和TimerTask,以便在所需的时间间隔内正确地运行扫描。

但是,我希望能够在用户按下按钮时停止和开始扫描,但目前我无法停止然后重新启动计时器和计时任务。

以下是我的代码

TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();

public void doWifiScan(){

scanTask = new TimerTask() {
        public void run() {
                handler.post(new Runnable() {
                        public void run() {
                         wifiManager.scan(context); 
                         Log.d("TIMER", "Timer set off");
                        }
               });
        }};


    t.schedule(scanTask, 300, 30000); 

 }

  public void stopScan(){

   if(scanTask!=null){
      Log.d("TIMER", "timer canceled");
      scanTask.cancel();
 }

}

计时器和任务启动得很好,每30秒扫描一次,但我无法停止它,我可以停止计时器,但任务仍然发生,scanTask.cancel()也似乎没用。

有更好的方法吗?还是我在计时器/计时器任务类中漏掉了什么?

3个回答

27
您可以考虑以下几点:
  • 检查调用cancel()的布尔返回结果,它应该指示您的请求成功或失败
  • Timer上尝试使用purge()cancel(),而不是在TimerTask上使用

如果您不一定需要TimerTimerTask,您总是可以使用postDelayed()(在Handler和任何View上都可用)。这将安排一个Runnable在延迟后在UI线程上执行。要使其重复出现,只需在执行您的周期性工作之后再次安排它自身即可。然后,您可以监视一个布尔标志以指示此过程何时应该结束。例如:

private Runnable onEverySecond=new Runnable() {
    public void run() {
        // do real work here

        if (!isPaused) {
            someLikelyWidget.postDelayed(onEverySecond, 1000);
        }
    }
};

我尝试检查scanTask上的布尔值,像这样boolean tf = scanTask.cancel();但是我现在在那一行上得到了一个空指针异常。然而任务本身运行良好?最终我将在Service中运行代码,所以使用postDelayed是否可行? - Donal Rafferty
很明显,scanTask被重置为null,从你展示的代码片段中无法确定为什么或如何。在Service中使用postDelayed()不是一个可选项,但在这种情况下为什么你想/需要一个Service还不清楚。 - CommonsWare
scanTask在整个应用程序的代码中没有被使用过,Timer也是如此。我发布的是Timer t和TimerTask scanTask的全部使用情况。我想创建一个几乎没有UI的应用程序,所以从阅读Android的资料来看,使用服务是实现这一目标的方法? - Donal Rafferty
我也遇到了同样的问题,我尝试了取消和清除计时器。如果我退出页面(返回或主页),我会在onPause和onStop中取消。线程将按其剩余时间运行 - 我无法取消计时器或中断线程?!除非我的代码(类似于此)有误,否则它不会像文档中描述的那样运行。 - mobibob
作为顶级停止计时器,我需要同时使用清除和取消功能,还是只需要使用其中一个? - LiangWang

6
使用您的代码,而不是

scanTask.cancel();

正确的方法是取消您的定时器(而不是timerTask):

t.cancel();

5
Android文档中指出,cancel()方法会取消定时器和所有预定任务。如果当前有任务正在运行,则不受影响。不能在此计时器上安排更多任务。后续调用不起任何作用。这解释了问题所在。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接