我有一个应用程序,播放一个MP3文件,我试图更新自定义字段与某些时候我们有声音播放列表(有点像卡拉OK效果)同步。我正在使用Handler
来安排这些更新。在我的自定义字段级的,我定义应该是在正确的时间运行更新一个Runnable
:问题同步声音和显示
private final Runnable mTrigger = new Runnable() {
@Override
public void run() {
int now = mPlayer.getCurrentPosition();
if (mState == STATE_PLAYING && mUpdateAction != null) {
if (mTriggerTime - now > MAX_PREMATURE_TRIGGER) {
// Sound is lagging too much; reschedule this trigger
mHandler.postDelayed(this, mTriggerTime - now);
} else {
// Run the update
mUpdateAction.run();
}
}
}
};
当我打电话mPlayer.start()
我计划通过调用mHandler.postDelayed(mTrigger, timeToFirstUpdate)
第一次更新。每个更新操作决定下一次更新的内容并安排它(通过调用mHandler.postDelayed(mTrigger, timeToNextUpdate)
)。更新时间通常是几百毫秒。
问题是,虽然有些更新在预定时间内即时发生,但其他更新可能会延迟200毫秒或更长,这对用户来说非常明显。除了播放声音之外,我在这些更新之间没有在应用程序中做任何事情。 (没有后台工作线程,没有其他显示更新。)延迟似乎是随机的,每次都会有相当大的变化。
我不认为postDelayed
的时机会是这样不准确!我不知道这是模拟器问题还是我的方法存在问题。声音播放是否搞砸了UI线程循环的时间?我应该将时间移动到后台线程中(并且可以安全地从后台线程中调用mPlayer.getCurrentPosition()
)?还有别的吗?