3

私はアンドロイド用のメトロノームを作っています。時間をキャプチャするだけの場合は、1 ~ 5 ミリ秒の精度で play_tick() 関数を実行できますが、さらにサウンドを再生したい場合、システムは不正確になります (最悪の場合は 10 倍)。これを改善する方法についての手がかりはありますか?場合によっては、システムがティックの再生を完全にランダムにスキップすることもあります。タスクの優先度を上げる方法はありますか、またはスケジューラはバックグラウンドで実行されている Android タスクを優先しますか? しばらく探しましたが、手がかりは見つかりませんでした。

すべての助けをいただければ幸いです!

コードを少し更新しました。

public void soundMetronome(){
    MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.click);
    metronome = new TimerTask() {
            public void run() {
                    handler.post(new Runnable() {
                            public void run() {
                                if(counter<SAMPLE_LENGTH){
                                            store_time[counter] = System.currentTimeMillis();
                                    mp.start(); 
                                    counter++;
                                    Log.d("TIMER", "Timer set off");
                                }
                                else{
                                    stopScan();
                                                                        }
                            }
                   });
            }};


            t.scheduleAtFixedRate(metronome, 0, SAMPLE_INTERVAL_MS); 

        }

ただし、500 ミリ秒前後の間隔では、依然としてひどく不正確です。約 1000ms の間隔では、非常に安定しています。問題はタイマー タスク自体ではありませんが、currentTimeMillis() と MediaPlayer からの PLAYBACK_COMPLETE メッセージを読み取る間に、一部のネイティブ Android プロセスが中断するようです。

mp.start() の後に mp.prepare() を呼び出して、タイマー関数が呼び出されたときにすぐにメディアプレーヤーを実行できるようにする方法はありますか?

Galaxy S3 と Android 4.1 を使用しています

ありがとう

4

1 に答える 1

1

精度の欠如は、ガベージ コレクションが原因です。ティックごとに新しいオブジェクトの作成を取り除くようにしてください。あなたのコードでは、MediaPlayer毎回 new が作成されますplay_tick、間違いなく一度だけ初期化する必要があります(ところで、MediaPlayer.release呼び出しがありません)。

また、 andの代わりにHandler.postDelayedを使用することもできます。TimerTaskHandler.post

于 2012-10-12T15:37:13.353 に答える