1

我有一个简单而经典的声明,即每 200 毫秒播放一个声音(节拍器)。

我使用处理程序编写它,然后以另一种方式使用线程。两种方式的问题都是一样的:当我按下硬件主页按钮时,或者当我按下按钮打开 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);
   }

};

4

3 回答 3

0

您是否使用某种暂停语句在节拍之间等待?您可以尝试将计时基于系统时钟值的倍数。这样一来,您可能仍然会得到较晚(或根本没有)发生的节拍,但您不会放慢速度。希望这有某种意义。

这更像是评论,但我还没有足够的代表发表评论。

于 2010-10-27T18:12:54.607 回答
0

我的手机似乎可以播放 MIDI 文件,这是一种非常紧凑的声音表示方式,也许您可​​以动态创建一个并将其用于节拍器?我假设合成处理的级别低于您通常可以访问的级别,因此时间会更好,但我不知道这是事实。

于 2010-10-27T18:16:29.430 回答
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);
于 2016-01-07T05:40:11.303 回答