I\'m developing a metronome application. The user can select at runtime the bpm, and my app will play the \"tick\" sound accordingly. The \"tick\" is a single metronome \"sh
You could try to use a TimerTask scheduled for fixed-rate execution on a Timer.
Timer and TimerTask are both part of the Android SDK (and Java SE). The executions do not delay because of execution time of the previous event.
Timer timer = new Timer("MetronomeTimer", true);
TimerTask tone = new TimerTask(){
@Override
public void run(){
//Play sound
}
};
timer.scheduleAtFixedRate(tone, 500, 500); //120 BPM. Executes every 500 ms.
You can then cancel the TimerTask when you need to change the BPM.
tone.cancel();
tone = new TimerTask(){...}
timer.scheduleAtFixedRate(tone, 1000, 1000); //60 BPM. Executes every 1000 ms.
Another possibility that may meet your requirements (from your comments) is spinning a thread and checking System.nanoTime() and sleeping in increments but spinning when you get close to wake up.
long delayNanos = 500000000;
long wakeup = System.nanoTime() + delayNanos; //Half second from right now
long now;
while(!done){
now = System.nanoTime();
//If we are less than 50 milliseconds from wake up. Spin away.
if(now <= wakeup - 50000000){
//Sleep in very small increments, so we don't spin unrestricted.
Thread.sleep(10);
}
if(now >= wakeup){
//Play sound
wakeup += delayNanos;
}
}