我有一个简单,经典的声明,每200毫秒播放一次声音(一个节拍器)。
我使用Handler编写它,然后以另一种方式使用Threads编写。 问题在两方面都是一样的:当我按下硬件主页按钮时,或者只是当我按下按钮打开ListView时,节拍器会慢慢减速一段时间。
这个问题(不是那么强大,但无论如何都存在)也没有做任何事情,让应用程序处于前台。
有什么想法吗?
以下是代码:
公共类节拍器实现了Runnable {
private Handler mHandler = new Handler();
public static long mStartTime;
Main mainContext;
public Metronomo(Main context) {
mainContext = context;
}
public void play() {
mStartTime = System.currentTimeMillis();
mHandler.postDelayed(this, 100);
}
public final void stop(){
mHandler.removeCallbacks(this);
}
public void run(){
//play the ogg file in position 1
mSoundManager.playSound(1);
//reschedule the next playing after 200ms
mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);
}
};
答案 0 :(得分:0)
你是否正在使用某种暂停声明在节拍之间等待?您可以尝试将时序基于系统时钟值的倍数。这样你可能仍会得到迟到(或根本没有)的节拍,但你不会慢下来。希望有某种意义。
这是一个更多的评论,但我还没有足够的代表来发表评论。
答案 1 :(得分:0)
我的手机似乎可以播放midi文件,这是一种非常紧凑的声音表达方式,也许你可以动态创建一个并用于节拍器?我假设合成的处理水平低于通常可以访问的水平,因此时间会更好,但我不知道这个事实。
答案 2 :(得分:0)
当播放此播放声音时
mSoundManager.playSound(1);
Android会等到该通话结束后再拨打
mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);
但是,如果您撤消这些调用,您可能会发现时间更准确。
mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);
mSoundManager.playSound(1);
你不能指望你的声音花费相同的时间来播放,所以告诉处理程序首先发布是更好一点。然而,仍然不理想。
另一个考虑因素是你重新计算正常运行时间并增加一些时间(在这种情况下为200)。为什么不在正常运行时间使用模数运算符,以确保您的下一个请求的发布时间更准确?
long divisions = SystemClock.uptimeMillis() % 200; // precisely scheduled event timings since system boot.
long nextDivision = divisions + 1; // the next desired event timing
mHandler.postAtTime(this, nextDivision * 200); // scaled back up to number of milli seconds
// now do more heavy lifting that would otherwise have affected uptimeMillis call
mSoundManager.playSound(1);