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

Posted

技术标签:

【中文标题】Android - 使用 Timer 和 TimerTask 控制任务?【英文标题】:Android - Controlling a task with Timer and TimerTask? 【发布时间】:2011-01-10 19:55:33 【问题描述】:

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

我已使用 Timer 和 TimerTask 让扫描按照我需要的时间间隔正确运行。

但是我希望能够在用户按下按钮时停止和开始扫描,而我目前在停止然后重新启动 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() 似乎也不起作用。

有没有更好的方法来做到这一点?还是我在 Timer/TimerTask 类中遗漏了什么?

【问题讨论】:

【参考方案1】:

你可以考虑:

检查对您的任务调用 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();但我现在在那条线上得到一个空指针异常。但是任务本身运行良好?我最终将在服务中运行代码,所以使用 postDelayed 是一种选择吗? 显然,scanTask 被重置为null,从您提供的代码片段中无法说出原因或方式。 postDelayed() 不是 Service 中的一个选项,但在这种情况下您为什么想要/需要 Service 尚不清楚。 scanTask 在整个应用程序的代码中其他地方没有用到,Timer 也没有,我贴的是Timer t 和TimerTask scanTask 的全部使用。我想创建一个 UI 最少甚至没有 UI 的应用程序,所以通过阅读有关 Android 的服务可以做到这一点? 对我来说同样的问题,我已经尝试取消和清除计时器。如果我退出页面(返回或主页),我会取消 onPause 和 onStop。线程在剩余时间内运行——我无法取消计时器或中断线程?!除非我的代码(与此类似)错误,否则这与记录的行为不符。 作为停止计时器,我需要同时使用清除和取消,还是清除或取消?【参考方案2】:

使用您的代码,而不是

scanTask.cancel();

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

t.cancel();

【讨论】:

【参考方案3】:

Android 文档说 cancel() 取消定时器和所有计划任务。如果有当前正在运行的任务,则不受影响。不能在此计时器上安排更多任务。随后的调用什么也不做。这解释了这个问题。

【讨论】:

以上是关于Android - 使用 Timer 和 TimerTask 控制任务?的主要内容,如果未能解决你的问题,请参考以下文章

android中的Timer与Handler的比较

Linux 编程之时间篇:wall time, cpu time 和 timer

Linux 编程之时间篇:wall time, cpu time 和 timer

Linux 编程之时间篇:wall time, cpu time 和 timer

go语言time包的学习(Time,Location,Duration,Timer,Ticker)

Python定时事件 Timer & sched