2011-12-06 5 views
0

私の質問はJavaに固有のものではありませんが、私が望むものを達成するために使用している言語です。アプリケーションを継続的にループする正しい方法は何ですか

私はJavaでBluetoothを試しています。簡単な端末プログラム、つまり近くのBluetoothデバイスを検索してリストするGUIインターフェイスはありません。

import javax.bluetooth.*; 

public class BluetoothTest implements DiscoveryListener{ 

    private static boolean isAlive = true; 

    public static void main(String[] args) { 
     try { 
      LocalDevice ld = LocalDevice.getLocalDevice(); 
      if (LocalDevice.isPowerOn()){ 
       System.out.println("Power On."); 
       System.out.println("Friendly Name: " + ld.getFriendlyName()); 
       System.out.println("Address: " + ld.getBluetoothAddress()); 
       DiscoveryAgent da = ld.getDiscoveryAgent(); 
       da.startInquiry(DiscoveryAgent.GIAC,new BluetoothTest()); 
       while (isAlive){ 
        /* Sleep */ 
        try { 
         Thread.sleep(200); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      } else { 
       System.out.println("Power Off."); 
      } 
     } catch (BluetoothStateException e) { 
      System.out.println(e.toString()); 
     } 
    } 

    public void setAlive(boolean status){ 
     isAlive = status; 
    } 

    public void deviceDiscovered(RemoteDevice rd, DeviceClass dc){ 
     try{ 
      System.out.println(rd.getFriendlyName(true)); 
     } catch (java.io.IOException e){ 
      System.out.println(e.toString()); 
     } 
    } 

    public void inquiryCompleted(int discType){ 
     isAlive = false; 
    } 

    public void servicesDiscovered(int transID, ServiceRecord[] sr){ 
    } 

    public void serviceSearchCompleted(int transID, int respCode){ 
    } 
} 

()DiscoveryAgentオブジェクトのstartInquiryはすぐに返され、発見されているすべてのデバイスは、私が実装したDiscoveryListenerインターフェイスに返されます。次のように私のコードです。問題は、デバイスが発見される前にプログラムが終了するwhile()ループを含まない限りです。

アプリケーションを効率的に常駐させるにはどうすればよいですか?これは、別々の「作業中の」スレッドと、作業スレッドを生成するメインスレッドを持つことによって達成されますが、作業者が終了するまでそれ自身が眠りますか?

答えて

2

BluetoothTestが一般的なオブジェクトロックを通知するまで、オブジェクト待機/通知メカニズムを使用してメインメソッドを保持できます。


だけ擬似コード、

は静的最終オブジェクト_mutex =新しいオブジェクト(定義)。

startInquiryの呼び出し後のメインメソッド_mutex.wait();これはメインスレッドを保持します。

In inquiryCompleted call _mutex.notify();これにより、メインスレッドが解放されます。


このコードは、startInquiryが新しいスレッドを作成してコールバックメソッドを呼び出す場合にのみ機能することに注意してください。私はDiscoverAgentクラスについてあまり気づいていません。したがって、そうでない場合は、上記の解決策が機能するようになります。

1

Javaプログラムは、「デーモン」としてマークされていないすべてのスレッドが終了するまで実行されます。 Mainスレッドが終了し、他のスレッドが実行されていない場合、プログラムは終了します。 「デーモン」スレッドではない別のスレッドを生成した場合(またはDiscoveryAgentが別のスレッドで実行されている場合)、Javaはスレッドが終了するまで実行を継続します。ループをメインに置くことは良い方法ですが、@ yatanpで述べたように、wait/notifyを使う方がよりクリーンです。あなたのコードに関する事柄の

カップル:

  • 自分のメインコードがまたあなたのDiscoveryListenerも持っている奇妙です。私は別のクラスでその機能を分離します:

    public class BluetoothTest { 
        ... 
        private static class OurListener implements DiscoveryListener { 
        } 
    } 
    
  • あなたは同じ変数isAliveから読んでいる2つのスレッドを持っているので、それはvolatileとしてマークされなければならないか、その周りsynchronizeする必要があります。
+0

あなたの答えをありがとう。確かに私のコードは非常に荒く準備ができており、テストコードだけです。これは、Bluetoothディスカバリが完了する前にスレッドが完了しているという問題が原因で発生しました。したがって、この問題は(正しくプログラムする方法を試して理解するために) – Kerry

関連する問題