0

ヘッドフォンがシステムに接続されていることを検出し、ヘッドフォンを取り外したときに別のコードを実行するプログラムを作成しようとしています。コードは正常に動作していますが、私が直面している問題は、デバイスのステータスがキャッシュされているため、ヘッドフォンを抜いてからわずか 1 分でプログラムが削除されたことを検出することです。これは、コードを実行すると無限ループになります。

しかし、ループではなく単一のインスタンスを実行すると、実行時にすぐに正しいステータスが表示されます

コードは次のとおりです。

        public class Headphonecheck {

             public static int hpfound = 0;
             public static int hpnfound =0;

             public static void isHeadphoneAvailable() {
                while (true)
                    {
                  if     (!AudioSystem.isLineSupported(Port.Info.HEADPHONE) && hpnfound ==0) {
                        System.out.println("NO HEADPHONE FOUND");
                       System.out.println("Do something else");
                       hpfound = 0;
                       hpnfound = 1;

                    } else {
                    if(AudioSystem.isLineSupported(Port.Info.HEADPHONE) && hpfound ==0){
                       System.out.println("HEADPHONE FOUND");
                       System.out.println("Do something");
                       hpnfound = 0;
                       hpfound =1;
                    }
                }

                } //close while

            }

        public static void main (String[] args){
            isHeadphoneAvailable();
        }
}

while ループを削除してコードを実行すると、1 回の実行で完全に機能します。つまり、ヘッドフォンを接続してコードを実行すると、HEADPHONE FOUND と表示され、ヘッドフォンを取り外してコードを実行すると、NO HEADPHONE FOUND と表示されます。

ヘッドフォンを装着してコードを実行すると、While ループで 1 回、HEADPHONE FOUND と表示され、すぐにヘッドフォンを取り外すと NO HEADPHONE FOUND と表示されるまでに約 50 秒かかります。これは、50 秒間キャッシュしてからキャッシュをクリアしているためです。

キャッシュを停止する方法、またはキャッシュをクリアする方法

4

2 に答える 2

0

イベントリスナーを追加する必要があるようです。この情報を探してループするのではなく、変更されたときに通知を受け取る必要があります。私はこれまでこのシステムを個人的に使用したことはありませんが、Lineインターフェイスを使用してイベント用のLineListenerを追加できるようです。

コードは次のようになります。

...

if(AudioSystem.isLineSupported(Port.Info.HEADPHONE) && hpfound ==0){ 
  Line line = AudioSystem.getLine(Port.Info.HEADPHONE);
  line.addLineListener(new LineListener() {
       public void update(LineEvent event) {
         switch (event.getType()) {
           CLOSE: doSomethingOnClose();
           STOP: doSomethingOnStop();
           // etc...
         }
       }
     });
}

...
于 2012-07-05T20:57:05.690 に答える
0

目標のレイテンシはどれくらいですか?

繰り返しの「シングルラン」を設定できますか? (たとえば、タイマー経由?)

「スライス」に対してwhileループが継続的に実行され、その応答が「スライス」のサイズと間隔に関連していることを期待しています。しかし、スレッドは通常 50 秒前に実行されません! 50 ミリ秒でも少し過剰です。そのため、取得しているキャッシュの量を完全に説明することはできません。

いずれにせよ、while ループを実行するのは、発生頻度が低く、たとえば 50 ミリ秒の精度しか必要としないイベントの場合、CPU の点でコストがかかるように思えますか? (現在、while ループは連続するマイクロ秒またはナノ秒をテストしていますが、厳密には高利益のテストではありません。) 50 ミリ秒ごとに 1 つのポーリングを繰り返すタイマー ループは、全体のリソースを大幅に有効に使用する必要があります。

Timer ルートを使用する場合の追加の注意: ScheduledThreadPoolExecutor は、「Java Concurrency in Practice」で Goetz/Bloch/Lea/others によって、util.Timer よりも優れており、Java 1.5 以降で優先されると宣伝されています。彼らは、チェックされていない例外をより適切に処理すると言っています。

別の可能性: Thread.sleep(50) またはそのような値を while ループに入れると、TimerTasks を使用するのと同等の方法で役立つ場合があります。

これで問題が解決するとは断言できませんが、少なくとも結果として「キャッシュ」がそれほど大きくならず、パフォーマンスが全体的にわずかに向上するはずです。

于 2012-07-05T19:48:57.223 に答える