【问题标题】:Android: Pause/Resume Timer OR ThreadAndroid:暂停/恢复计时器或线程
【发布时间】:2013-12-21 09:14:40
【问题描述】:

我已经检查了有关如何暂停/恢复计时器的所有 SO 答案,但找不到解决方案。

我创建了一个 Timer 任务,它计算员工的工作时间并将其放在 TextView 中进行显示。

代码如下:

Timer T = new Timer();
    T.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    String workingTime = "Your effort is "
                            + format.format(Double.valueOf(hr)) + ":"
                            + format.format(Double.valueOf(min)) + ":"
                            + format.format(Double.valueOf(sec))
                            + " till now for the day";
                    storeEffort.setText(workingTime);
                    sec++;
                    if (sec > 59) {
                        sec = 0;
                        min = min + 1;
                    }
                    if (min > 59) {
                        min = 0;
                        hr = hr + 1;
                    }
                }
            });
        }
    }, 1000, 1000);

其中 storeEffort 是我的 TextView,它显示了卡在正在运行的线程中的工作时间(主要问题)。我想通过单击按钮暂停努力计时器,并在再次单击相同按钮时恢复它。还有其他方法可以完成此类任务吗?

【问题讨论】:

    标签: java android multithreading timer


    【解决方案1】:

    您的解决方案可能有一个小问题 - 您正在使用计时器来计算时间间隔,而无需这样做。您可以使用即StopWatch 来计算经过的时间。因此,无需在计时器作业中添加秒数,您只需从该计时器中获取经过的时间。要暂停计时器,您可以调用stopWatch.stop() 并启动它,您可以调用stopWatch.start()

    它可能看起来像这样:

    Stopwatch stopwatch = Stopwatch.createStarted();
    
    void startThreadUpdateTimer(){}
        Timer T = new Timer();
        T.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String workingTime = "Your effort is " + sw.toString() + 
                             " till now for the day";                        
                    }
                });
            }
        }, 1000, 1000);
    }
    
    public void pause(){
        if(stopwatch.isRunning()){
            stopwatch.stop();
        }
    }
    
    public void resume(){
        if(!stopwatch.isRunning()){
            stopwatch.start();
        }
    }
    

    【讨论】:

    • 嗯,定期通话怎么样?
    • 定期通话?我不确定我是否理解这是什么。我的建议似乎与 OP 的要求相同。
    • docs.oracle.com/javase/7/docs/api/java/util/concurrent/…, long, long, java.util.concurrent.TimeUnit) 最后两个参数提供了任务执行的周期——周期性调用
    • @BorisStrandjev 我已经更新了代码,希望现在更好。
    • 那么首先我必须创建您发送的链接的秒表类.. ..right
    【解决方案2】:

    UPDATE如果定时器需要每隔一秒从头开始的解决方法:

    public class YourOuterClass extends Activity {
        private YourTimerTask mTimerTask;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Button button;
            button.setOnClickListener(new OnClickListener() {
    
                public void onClick(View v) {
                    if (mTimerTask != null && mTimerTask.isTaskActive()) {
                        mTimerTask.deactivateTimer();
                        mTimerTask = null;
                    } else {
                        startTask();
                    }
    
                }
            });
            ...
        }
    
       private class YourTimerTask extends TimerTask {
           private boolean mIsTimerActive;
    
           public YourTimer() {
               mIsTimerActive = true;
           }
    
           public void deactivateTimer() {
               mIsTimerActive = false;
           }
    
           public boolean isTaskActive() {
               return mIsTimerActive;
           }
    
           @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String workingTime = "Your effort is "
                                + format.format(Double.valueOf(hr)) + ":"
                                + format.format(Double.valueOf(min)) + ":"
                                + format.format(Double.valueOf(sec))
                                + " till now for the day";
                        if (!mIsTimerActive) {
                            cancel(); // will cancel this timer instance
                        }
                        sec++;
                        if (sec > 59) {
                            sec = 0;
                            min = min + 1;
                        }
                        if (min > 59) {
                            min = 0;
                            hr = hr + 1;
                        }
                    }
                });
            }
       }
    ...
       private void startTask() {
          Timer T = new Timer();
          mTimerTask = new YourTimertask();
          T.scheduleAtFixedRate(mTimerTask, 1000, 1000);
       }
    }
    

    【讨论】:

    • ..我仍然无法暂停计时器。当我单击按钮时,它仅在前台暂停,但仍在后台运行。当我再次单击按钮时,它会继续当前时间而不是暂停时间。任何想法
    • @RanjitPati 当然,只需在每次单击按钮时重置值。但是,如果您想从 0 重新启动它,我认为有更好的解决方案。我将在我的答案中添加它。
    • 对不起鲍里斯。你还是不明白我的问题。我想暂停和恢复时间。最好的例子是多次刷卡/刷卡。从开始 swipeIn 计数器开始,当您想出去一段时间时,您必须刷出并且时间在那里暂停。然后当你进来并再次刷卡时时间恢复..
    • @RanjitPati 看到我的编辑,但现在我真的不确定我是否理解这个问题。计时器真的应该恢复,还是重新开始?你应该支持多个实例吗?
    • 我有两个按钮。如果您单击 first1,则计时器将启动。当您单击第二个时,它会暂停。当您单击第一个时,时间再次恢复。您的解决方案很好,但它只适用于前台。因为时间不会在后台停止。希望你能理解..
    猜你喜欢
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 2015-02-21
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多