更改 Android 系统时钟会停止计时器.我怎样才能重新启动它们? [英] Changing Android system clock stops timers. How can I restart them?

查看:53
本文介绍了更改 Android 系统时钟会停止计时器.我怎样才能重新启动它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 Android 应用程序中运行一个周期性任务.我目前使用这样的计时器:

I need to run a periodic task in an Android application. I currently use a timer like this:

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

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

This does exactly what I need, but there is a problem: if I change the time on the emulator or phone, the timer stops running. This is what appears in the log when I change the time:

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

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

Nothing about the timer being interrupted, but it clearly doesn't run anymore after the system clock has changed. I need the task to keep running all the time as long as the application is running.

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

How can I restart the timer if it gets stopped like this? There's no method on the Timer or TimerTask to check whether it's currently running, so I can't know when to reschedule it. Any ideas?

推荐答案

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

I think there are a few ways to do this. I wouldn't use the timer in either case.

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

You can use a handler to run your task in a postDelayed call. Your task would then have to re-register itself with the handler from within itself.

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,这种方式是半可预测的.使用主线程可能合适也可能不合适,具体取决于任务是什么.

This will keep the task running while your app is alive. You can also adjust the delayed rate in the postDelayed within the Runnable. This way is semi predictable as long as you make another Looper. Using the main thread may or may not be appropriate depending on what the task is.

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

There is also an AlarmManager, that you can gain access to via the Context interface, which is meant for recurring tasks tasks at more precise intervals. It's a little more complex to use but you get the flexibility of having use of the RTC and persisted repeatable tasks.

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

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

For example, the pending intent can fire a broadcast intent that you can listen to elsewhere. You can create this pendingintent in the onCreate of your custom Application object and cancel the intent in the onTerminate().

这篇关于更改 Android 系统时钟会停止计时器.我怎样才能重新启动它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆