【问题标题】:Metronome Timer slowdown (via Handler, or Threads too)节拍器计时器减速(也通过处理程序或线程)
【发布时间】:2023-04-09 06:37:01
【问题描述】:

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

我使用处理程序编写它,然后以另一种方式使用线程。 两种方式的问题都是一样的:当我按下硬件主页按钮时,或者当我按下按钮打开 ListView 时,节拍器会严重减慢一段时间。

这个问题(不是很严重,但存在)也表示什么都不做,让应用程序处于前台。

有什么想法吗?

代码如下:

公共类 Metronome 实现 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);
   }

};

【问题讨论】:

  • 这是此类设备上精确计时的问题。完全不确定是否有解决方案,更不用说一个简单的解决方案了

标签: android timer real-time slowdown


【解决方案1】:

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

这更像是一个评论,但我还没有足够的代表离开 cmets。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 类似的想法:生成一个有节拍器声音然后是静音的声音流,而不是播放声音然后停止。只要您的线程获得足够的 CPU 时间来保持声音缓冲区已满,您的节拍器就会保持准时,即使系统中的其他东西处于活动状态。
    【解决方案3】:

    当这个播放声音被调用时

    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);
    

    【讨论】:

      猜你喜欢
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多