私はmp3ファイルを再生するアプリケーションを持っており、サウンド再生(カラオケエフェクトのようなもの)のために集計した特定の時間と同期してカスタムフィールドを更新しようとしています。私はこれらの更新をスケジュールするのに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();
}
}
}
};
私はmHandler.postDelayed(mTrigger, timeToFirstUpdate)
を呼び出すことにより、最初の更新をスケジュールmPlayer.start()
を呼び出すとき。各更新アクションは、次の更新内容を決定し、スケジュールを設定します(mHandler.postDelayed(mTrigger, timeToNextUpdate)
を呼び出して)。更新時間は、通常、数百ミリ秒離れている。
問題は、予定された時間にすぐに更新が行われるのに対し、他のものは200ミリ秒以上遅延することがあります。これはユーザーにとってはかなり目立ちます。私はサウンドを再生する以外のこれらの更新の間に私のアプリで何もしていない。 (バックグラウンドのワーカースレッドはなく、他のディスプレイの更新はありません)。遅延はランダムに見え、毎回大幅に異なります。
私はpostDelayed
のタイミングがこの不正確であるとは思わなかった!これがエミュレータの問題か私のアプローチの問題かどうかは分かりません。サウンドの再生がUIスレッドループのタイミングを悪化させますか?タイミングをバックグラウンドスレッドに移動する必要があります(バックグラウンドスレッドからmPlayer.getCurrentPosition()
を呼び出すのは安全ですか)。他に何か?