0

I need to execute code at intervals, sometimes 10 seconds, sometimes 5 minutes. The code should be executed at exact 10 seconds from start, then at exact 5 minutes and 10 seconds from start, etc.
A Chronometer is ticking along from the start, so the execution time must be accurate.

Using Handler.postDelayed does not work, because the code to execute could take some time. The next execution of the code could be late when that happens.

When I wanted to implement AlarmManager, I saw the note

The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.

So I'm a bit confused, how should I do this to guarantee correct execution?

nhaarman
  • 98,571
  • 55
  • 246
  • 278

5 Answers5

1

Have a look at this post : Time/Date change listener. you can use setRepeating() method, or alternatively set the timer again after each execution.

Community
  • 1
  • 1
Zardaloop
  • 1,594
  • 5
  • 22
  • 43
1

As android is not a hard-realtime OS, exact timing of execution is not possible without substantial kernel modifications. Even there, you are unlikely on a typical android device to have much in the way of exactly timed means of useful I/O, so just running your code at the perfect time may not be enough.

At best you can determine using the more reliable of the timers the latest point at which your code could have run, and take after-the-fact compensation measures.

In terms of the available timing methods, a major consideration should be if you intend the device to wakeup from sleep to accomplish events, in which case you should use the Alarm Manager, if you intend to keep the device awake, in which case you should use a Wake Lock, or if you are okay with your events happening only when the device is awake and your service or activity is running, in which case you can use a simple Timer.

Chris Stratton
  • 39,853
  • 6
  • 84
  • 117
1

As Chris stated, there's no such thing as exact timing in Android.

But you could try it like this to come near realtime...

some Pseudocode for waiting 5s:

class mJob implements Runnable{
   public void run(){
      while(System.currentTimeMillis()<myExactTime){ //poll for your time
         Thread.sleep(1);
      }
      //Ok, we are as near as we'll ever get
      //call here your 'realtime' function or whatever you need
   }
}

 mHandler.postDelayed(mJob,4950); //the closer to 5000, the better for the cpu but you could miss your `myExactTime`

I don't now how exact this is, you'll just have to try it. But I see no other way to become more 'realtime' with the normal SDK. You could even remove the sleep(1) to become even closer to your myExactTime.

For the next call use something like this (scratch):

nextCallDelayInMillis = starttimeInMillis+No1_Delay+No2_Delay-System.currentTimeMillis();

trichner
  • 840
  • 1
  • 11
  • 22
1

You didn't specify if your code runs while application is running or as background service. It's important, because after you lock your device, Android goes to sleep mode, where CPU is off and functions like postDelayed wont be activated. Intents asking to start activities too. But AlarmManager broadcasts will. I'll quote from here

The AlarmManager is best used for tasks that need to run even when the application isn’t open. For normal timing operations that need to run during application use (ticks, timeouts, etc), it is more efficient to use the postDelayed() and postAtTime() methods of a Handler. The AlarmManager requires too much overhead to justify it being used this way.

RealNmae
  • 630
  • 9
  • 20
0

I suggest you to use postDelay, for any post to handler, handler is opening new thread and code is executing simultaneously.

private Runnable mUpdateTimeTask = new Runnable() {
public void run() {

//some code

mHandler.postDelayed(this, 1000);
}
};

Here is my complete code I used postDelay for displaying count down timer: https://github.com/minimaldevelop/antistress/blob/master/src/com/minimaldevelop/antistress/AntiStressExerciseActivity.java

Also here I using AlarmManger but only as remainder to display message at notification bar when application is closed.

zarej
  • 913
  • 1
  • 11
  • 23