0

我正在尝试编写一个程序来检测耳机何时插入系统,然后在您移除耳机时运行另一段代码。代码工作正常,但我面临的问题是设备的状态正在被缓存,所以在我拔出耳机后仅 1 分钟我的程序检测到它已被移除。当我运行代码时会发生这种情况,这是一个无休止的 while 循环。

但是如果我不在循环中运行单个实例,它会在运行时立即显示正确的状态

这是代码:

        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循环并运行代码,它可以完美地用于单次运行..即您插入耳机并运行代码它显示HEADPHONE FOUND,然后当您移除耳机并运行代码时它显示NO HEADPHONE FOUND。

在while循环中,如果你有耳机并运行代码,它会显示HEADPHONE FOUND,然后如果你立即取下耳机,大约需要50秒才能显示NO HEADPHONE FOUND。这是因为它正在缓存 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 毫秒也有点过分。因此,这不能完全解释您获得的缓存量。

无论如何,对于不经常发生并且可能只需要 50 毫秒精度的事件而言,像您一样运行 while 循环在 CPU 方面似乎代价高昂?(目前,while 循环正在测试连续的微秒甚至纳秒,而不是一个完全高回报的测试。)每 50 毫秒重复一次轮询的 Timer 循环应该可以更好地利用周围的资源。

另外一点,如果您采用 Timer 路线:Goetz/Bloch/Lea/others 在“Java Concurrency in Practice”中吹捧 ScheduledThreadPoolExecutor 优于 util.Timer,并且是 Java 1.5 及更高版本的首选。他们说它在处理未经检查的异常方面做得更好。

另一种可能性:在您的 while 循环中放置一个 Thread.sleep(50) 或类似的值,这可能有助于以等同于使用 TimerTasks 的方式。

我不能肯定这会解决问题,但至少“缓存”不会因此而变得如此之大,并且整体性能应该会略有提高。

于 2012-07-05T19:48:57.223 回答