【问题标题】:Changing Android system clock stops timers. How can I restart them?更改 Android 系统时钟会停止计时器。我怎样才能重新启动它们?
【发布时间】:2011-03-14 17:03:04
【问题描述】:

我需要在 Android 应用程序中运行定期任务。我目前使用这样的计时器:

final Handler guiHandler = new Handler();

// the task to run
final Runnable myRunnable = new Runnable() {

    @Override
    public void run() {
        doMyStuff();
    }
};

Timer timer = new Timer();
timer.schedule(new TimerTask() {

    @Override
    public void run() {
        guiHandler.post(myRunnable);
    }
}, 0, 30000); // run every 30 seconds

这正是我所需要的,但有一个问题:如果我更改模拟器或手机上的时间,计时器将停止运行。这是我更改时间时出现在日志中的内容:

D/SystemClock(  331): Setting time of day to sec=1278920137
W/SystemClock(  331): Unable to set rtc to 1278920137: Invalid argument

没有关于定时器被中断的问题,但是在系统时钟改变后它显然不再运行了。只要应用程序在运行,我就需要任务一直运行。

如果计时器像这样停止,我该如何重新启动? Timer 或 TimerTask 上没有方法来检查它当前是否正在运行,所以我不知道何时重新安排它。有什么想法吗?

【问题讨论】:

  • 这是 Android 的错误吗?系统时钟设置应该停止和中断应用程序似乎完全蹩脚。

标签: android timer systemtime


【解决方案1】:

我认为有几种方法可以做到这一点。在这两种情况下我都不会使用计时器。

您可以使用处理程序在 postDelayed 调用中运行您的任务。然后,您的任务将不得不从自身内部向处理程序重新注册。

final int ONE_SECOND = 1000; // one second
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
   public void run() {
      ... // do some stuff
      if (expression) {
         handler.postDelayed(this, ONE_SECOND);
      }
   }
}, ONE_SECOND);

这将在您的应用处于活动状态时保持任务运行。您还可以在 Runnable 内的 postDelayed 中调整延迟率。只要您制作另一个 Looper,这种方式是半可预测的。根据任务的不同,使用主线程可能合适也可能不合适。

还有一个 AlarmManager,您可以通过 Context 接口访问它,用于以更精确的间隔重复执行任务。它使用起来稍微复杂一些,但您可以灵活地使用 RTC 和持久的可重复任务。

AlarmManager manager = mContext.getSystemService(Context.ALARM_SERVICE);
manager.setRepeating(AlarmManager.RTC, 
    <start_time_millis>, 
    <period_millis>, 
    pendingIntent);

例如,待处理的 Intent 可以触发您可以在其他地方收听的广播 Intent。您可以在自定义 Application 对象的 onCreate 中创建此 pendingintent,并在 onTerminate() 中取消该意图。

【讨论】:

  • 这是我正在寻找的绝佳解决方案!谢谢
猜你喜欢
  • 2020-06-20
  • 1970-01-01
  • 2018-11-25
  • 2022-12-15
  • 2011-02-11
  • 2014-06-05
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
相关资源
最近更新 更多