【问题标题】:How to stop the Timer thread?如何停止 Timer 线程?
【发布时间】:2015-08-17 08:00:55
【问题描述】:

如何停止 Timer 线程? 我有一个计时器线程,我想停止它。我该怎么做?

我试图通过停止线程来停止,但没有成功。 有任何想法吗? 提前感谢您的帮助

这是我的代码:

   public void startTimer() {
    startTime = System.currentTimeMillis();
    final Handler handler = new Handler();
    task =new Thread() {
        @Override
        public void run() {
            long millis = System.currentTimeMillis()-startTime;
            long secs = millis / 1000 % 60; // seconds, 0 - 59
            long mins = millis / 1000 / 60 % 60; // total seconds / 60, 0 - 59
            long hours = millis / 1000 / 60 / 60; // total seconds / 3600, 0 - limitless

            timeString = String.format("%02d:%02d:%02d", hours, mins, secs);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mtvtimer.setText(timeString);
                }
            });

            handler.postDelayed(task, 1000);

        }


    };
    task.start();


    }

【问题讨论】:

标签: android timer


【解决方案1】:

鉴于 Thread.stop 已被弃用,您唯一的选择是添加一些您自己的信号,例如您希望它停止时设置的布尔变量。

例如

boolean stop = false;
public void startTimer() {
    startTime = System.currentTimeMillis();
    final Handler handler = new Handler();
    task =new Thread() {
        @Override
        public void run() {
            if (stop) {
                return;
            }
            long millis = System.currentTimeMillis()-startTime;
            long secs = millis / 1000 % 60; // seconds, 0 - 59
            long mins = millis / 1000 / 60 % 60; // total seconds / 60, 0 - 59
            long hours = millis / 1000 / 60 / 60; // total seconds / 3600, 0 - limitless

            timeString = String.format("%02d:%02d:%02d", hours, mins, secs);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mtvtimer.setText(timeString);
                }
            });

           handler.postDelayed(task, 1000);
    }

从其他地方,你设置stop = true 来阻止它。 (这是一个粗略的示例代码,只是为了理解这个想法)

【讨论】:

  • 非常感谢它对我的帮助很大。
【解决方案2】:

从您发布的 sn-p 来看,您想要实现的目标还不是很清楚。您正在将任务传递给 TimerJob 的处理程序,同时调用 task.start() ,这意味着每次任务开始时,它都会将另一个任务附加到处理程序,只要使用线程。因此,如果我正确理解了您的逻辑,您可以执行以下示例:

 //Handler should be created only once , and should have the specified methods
 //in which he is needed to respond , 
 //for complicated tasks , create a new Specific Handler 
 final Handler handler = new Handler();
 //Defining Thread for example
 Thread task;
 public void startTimer() {
        startTime = System.currentTimeMillis();
        task =new Thread() {
            @Override
            public void run() {
                long millis = System.currentTimeMillis()-startTime;
                long secs = millis / 1000 % 60; // seconds, 0 - 59
                long mins = millis / 1000 / 60 % 60; // total seconds / 60, 0 -59
                long hours = millis / 1000 / 60 / 60; // total seconds / 3600, 0 - limitless

                timeString = String.format("%02d:%02d:%02d", hours, mins, secs);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mtvtimer.setText(timeString);
                    }
                //repeat the task
                handler.postDelayed(task, 1000);
                });     
            }

        };
        //No Reason To start an unmanaged thread 
        //task.start();
        //instead passing it to the handler , 
        //and still you can call interrupt on the task reference
        handler.postDelayed(task, 1000);

    }


//To call whenever you have to stop the task
public void stopHandlerTask()
{
     //your logic here
     handler.removeCallbacks(task);
}

【讨论】:

  • 这不会在线程完成任务后停止。这不是预期的结果。很明显,postDelayed 也必须从线程内调用。
  • 他没有建议何时停止处理程序,如果您在任务中调用 postDelayed,它将永远不会被调用,这就是他启动非托管线程的原因。现在,如果您尝试先使用 task.start() 调用线程,以便调用 postDelayed ,那么它将创建大量待处理的任务,只能通过手动取消处理程序来停止,如果您只是添加一个标志,这并不意味着处理程序已经停止调用异步任务,它仍然被调用但返回标志的原因
  • OP 使用了计时器这个词,暗示它应该在经过的时间跨度上重复。而且我从来没有建议线程应该不受管理。我只是说该任务需要运行多次。因此,线程需要在完成后自行发布。类似于这种方法的东西:stackoverflow.com/a/10207775/2027232 或我的答案。
  • @NicolasTyler ,是的,我明白你的意思(添加了一个编辑以像定时器任务一样工作),但如果他想要一个定时器任务,那么他会使用 TimerTask ,而不是每次创建一个非托管线程队列调用 startTimer() 的时间
  • 正确,java.util.Timer 或类似的东西会更好。
【解决方案3】:

这似乎是一个计时器的工作:

//references for the timer, task and start time.
Timer timer;
TimerTask task;
long startTime;

public void onCreate()
{
    task = new TimerTask() {
        @Override
        public void run() {
            long millis = System.currentTimeMillis()-startTime;
            long secs = millis / 1000 % 60; // seconds, 0 - 59
            long mins = millis / 1000 / 60 % 60; // total seconds / 60, 0 -59
            long hours = millis / 1000 / 60 / 60; // total seconds / 3600, 0 - limitless

            mtvtimer.setText(String.format("%02d:%02d:%02d", hours, mins, secs));
        }
    };
}

//start the timer
public void startTimer()
{
    timer = new Timer();
    timer.schedule(task, 1000, 1000);// start after 1 second and repeat after every second.
}

//stop the timer
public void stopTimer()
{
    if(timer != null) {
        timer.cancel();
        timer.purge();
        timer = null;
    }
}

【讨论】:

    猜你喜欢
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多