节拍器计时器减慢(通过处理程序或线程)
我有一个简单、经典的说法,即每 200 毫秒播放一次声音(节拍器)。
我使用处理程序编写它,然后以另一种方式使用线程编写它。 两种方式的问题都是相同的:当我按下硬件主页按钮时,或者只是当我按下按钮打开 ListView 时,节拍器会严重减慢一段时间。
这个问题(不是那么严重,但仍然存在)也表现为不执行任何操作并将应用程序留在前台。
有什么想法吗?
代码如下:
public class Metronome Implements 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);
}
};
I have a simple, classic, statement that every 200 milliseconds plays a sound (a metronome).
I wrote it using Handlers, and then in another way, using Threads.
The problem is the same in both ways: when I press hardware home button, or also simply when I press a button to open a ListView, the metronome terribly slowdown for a while.
This problem (not so strong, but however present) presents also doing nothing and leaving the application in foreground.
Any ideas?
Here's the code:
public class Metronome implements 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);
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否使用某种暂停语句在节拍之间等待?您可以尝试将计时基于系统时钟值的倍数。这样,您可能仍然会得到较晚出现(或根本不出现)的节拍,但不会减慢速度。希望这有某种意义。
这更像是一条评论,但我还没有足够的代表来发表评论。
Are you using some kind of pause statement to wait between beats? You could try basing the timing on multiples of a system clock value instead. That way you may still get beats that occur late (or not at all) but you wouldn't get a slow down. Hope that makes some kind of sense.
This is more of a comment but I don't have enough rep to leave comments just yet.
我的手机似乎能够播放 midi 文件,这是一种非常紧凑的声音表示方式,也许您可以动态创建一个文件并将其用于节拍器?我假设合成的处理级别比您通常可以访问的级别要低,这样时机会更好,但事实上我不知道这一点。
My phone seems to be able to play midi files, which are a pretty compact way to represent sound, perhaps you could dynamically create one and use that for the metronome? I'm assuming that the synthesis is handled at a lower level than would ordinarily be accessible to you so that the timing would be better, but I don't know that for a fact.
当这个播放声音被调用时,
Android会等到该调用完成,然后您再调用,
但是,如果您反转这些调用,您可能会发现计时更准确。
您不能指望您的声音会花费完全相同的时间来播放,因此告诉处理程序先发布会更好一些。然而,仍然不理想。
另一个考虑因素是您要重新计算正常运行时间并添加更多时间(在本例中为 200)。为什么不在正常运行时间上使用模数运算符,以确保更精确地安排下一个请求的发布时间?
When this play sound is called
Android waits until that call is finished, then you call
however, if you reverse those calls, you may find that the timing is more accurate.
You can't count on your sound taking exactly the same amount of time to play, so telling the handler to post first is a bit better. Still not ideal, however.
Another consideration is that you're re-computing uptime and adding some more time to that (200 in this case). Why not use the modulus operator on your uptime, to ensure that your next requested post time is more precisely scheduled?