【问题标题】:Timer function in Service (kind of chronometer)服务中的定时器功能(一种计时器)
【发布时间】:2013-03-23 10:34:19
【问题描述】:

我的目的是创建一个从 00:00:00 开始并与记录功能一起挂起的计时器。此记录是在 服务 中完成的,因此计时器也在同一服务中。如果应用程序移到后台,则记录和计时器会继续进行,并且应用程序会使用 myService.getTime() 在 onResume 处获取时间。

但我经历了两件奇怪的事情。 第一个是我的计时器有时比一秒快,有时慢,有时从例如 00:00:04 跳到 00:00:06 等。没有 没有一致性强>在里面。我使用下面的代码,但可能有更好的选择来解决这个问题? 第二个是它导致我的按钮滞后,尽管我是在服务中启动它?

服务

//////////TIMER FUNCTION START//////////

        private void startTimerClick() {

            if (stopped) {
                startTime = System.currentTimeMillis() - elapsedTime;
            } else {
                startTime = System.currentTimeMillis();
            }
            mHandler.removeCallbacks(startTimer);
            mHandler.postDelayed(startTimer, 0);

        }

        private void pauseTimerClick() {
            mHandler.removeCallbacks(startTimer);
            stopped = true;

        }

        private void stopTimerClick() {
            mHandler.removeCallbacks(startTimer);
            stopped = false;

        }

        private void startTimer() {

            startTimer = new Runnable() {
                public void run() {
                    elapsedTime = System.currentTimeMillis() - startTime;
                    updateTimer(elapsedTime);
                    mHandler.postDelayed(this, REFRESH_RATE);
                }
            };

        }

        private void updateTimer(float time) {
            secs = (long) (time / 1000);
            mins = (long) ((time / 1000) / 60);
            hrs = (long) (((time / 1000) / 60) / 60);

            /*
             * Convert the seconds to String and format to ensure it has a leading
             * zero when required
             */
            secs = secs % 60;
            seconds = String.valueOf(secs);
            if (secs == 0) {
                seconds = "00";
            }
            if (secs < 10 && secs > 0) {
                seconds = "0" + seconds;
            }

            /* Convert the minutes to String and format the String */

            mins = mins % 60;
            minutes = String.valueOf(mins);
            if (mins == 0) {
                minutes = "00";
            }
            if (mins < 10 && mins > 0) {
                minutes = "0" + minutes;
            }

            /* Convert the hours to String and format the String */

            hours = String.valueOf(hrs);
            if (hrs == 0) {
                hours = "00";
            }
            if (hrs < 10 && hrs > 0) {
                hours = "0" + hours;
            }


        }
        //////////TIMER FUNCTION END////////////


    public String getHours(){

        return hours;
    }

    public String getMinutes(){

        return minutes;
    }

    public String getSeconds(){

        return seconds;
    }
}

活动(/片段)

private void timerStart() {

        handler = new Handler();
        Thread t = new Thread() {

              @Override
              public void run() {
                try {
                  while (!isInterrupted()) {
                    Thread.sleep(1000);
                    handler.post(new Runnable() {
                      @Override
                      public void run() {

                          timer.setText(myService.getHours()+":"+myService.getMinutes()+":"+myService.getSeconds());
                      }
                    });
                  }
                } catch (InterruptedException e) {
                }
              }
            };

            t.start();

    }

【问题讨论】:

    标签: android service timer stopwatch chronometer


    【解决方案1】:

    您在服务和活动/片段代码中都使用线程。 在 Android 中将线程用于时间敏感的任务是一个问题,因为 Android 能够显着延迟线程。

    我一直在使用ScheduledThreadPoolExecutor 完成类似的任务,效果很好。

    然后你会像这样使用它:

    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); // where 1 is the number of needed concurrent threads. 1 should last for your needs.
    executor.scheduleWithFixedDelay(new TimerTask() {  
        // your recurringly executed code here
    }, 0, 1, TimeUnit.SECONDS);
    

    【讨论】:

    • 在服务中保存启动时间并在主要活动/片段中进行计时本身是否也是一种解决方案? @hoelle2011
    • 我猜你使用该服务来让你的应用在后台运行时保持活跃。当然可以在服务成员中保存开始时间,但也许另一个地方会更合适。如果您需要任何其他后台任务的计时器,那么您可能应该将其保留在服务中。想想在一定时间后创建通知之类的任务 - 即使用户界面不可见,因此活动/片段中的计时器可能无法执行。
    猜你喜欢
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    相关资源
    最近更新 更多