2016-05-20 5 views
0

私が取り組んでいるプロジェクトでは、この特定のメソッドを別のスレッドから呼び出す必要があることをユーザーに警告するカスタム注釈を付けたいと思います。私はそれを@ThreadNeededと呼びました。そして、呼び出されたメソッドがメインスレッド上にあれば、コンパイラに警告するという効果を得たいと思います。どうすればこれを達成できますか?私は注釈に関する多くのガイドを見てきましたが、実際に注釈でElementTypeをマークする以外には、それらを使用する方法はありません。ここで私はここで、これまでJavaアノテーションを便利にする方法

/** 
* An annotation that signifies that this method needs to be run inside a background thread. 
*/ 
@Retention(RetentionPolicy.SOURCE) 
@Target(ElementType.METHOD) 
public @interface ThreadNeeded { 

} 

を持っており、注釈のソースは、あなたが必要なものを行うことができます使用例

@Nullable 
    @ThreadNeeded 
    public SonyCamera build(){ 
     try { 
      send(); 
     } catch (Exception ex){ 
      Log.e(TAG, ex.getMessage(), ex); 
      return null; 
     } 
     return camera; 
    } 

    private void send() throws Exception { 
     final byte[] ssdpreqb = SSDP_REQUEST.getBytes(); 
     DatagramSocket socket; 
     DatagramPacket recieve, packet; 
     socket = new DatagramSocket(); 
     InetSocketAddress isad = new InetSocketAddress(SSDP_ADDRESS, SSDP_PORT); 
     packet = new DatagramPacket(ssdpreqb, ssdpreqb.length, isad); 
     socket.send(packet); 
     Thread.sleep(100); 
     socket.send(packet); 
     Thread.sleep(100); 
     socket.send(packet); 

     boolean searching = true; 
     byte[] array = new byte[1024]; 
     while(searching) { 
      recieve = new DatagramPacket(array, array.length); 
      socket.setSoTimeout(SSDP_TIMEOUT); 
      socket.receive(recieve); 
      String replyMessage = new String(recieve.getData(), 0, recieve.getLength(), "UTF-8"); 
      String ddusn = SSDPClient.findParamaterValue(replyMessage, "USN"); 
      String location = SSDPClient.findParamaterValue(replyMessage, "LOCATION"); 
      camera.location = location; 
      camera.usn = ddusn; 
      fetch(location); 
     } 
    } 
+1

コンパイラは、このコードが実行されるスレッドを知る手段を持っていません。コンパイル時にあなたが望むことをすることはできません。実行時には、AOPを使用して@ThreadNeededによって注釈が付けられたメソッドをインターセプトし、必要な処理を行うことができます。別のスレッドでこのコードを実行する必要がある場合は、別のスレッドとして記述してください。 – Andre

+0

注釈はこれを行う正しい方法ではありません。あなたのメソッドにjavadocを書いて、実行可能なスレッドと実行していないスレッドを明確に説明してください。例については、[EventQueue.invokeAndWait](http://docs.oracle.com/javase/8/docs/api/java/awt/EventQueue.html#invokeAndWait-java.lang.Runnable-)および[GraphicsContext]( http://docs.oracle.com/javase/8/javafx/api/javafx/scene/canvas/GraphicsContext.html)。 – VGR

答えて

1

ソースをコンパイル中に注釈を処理するには、注釈プロセッサーを作成してjavacに指示する必要があります。ここで

は、チュートリアルのいくつかの種類である:私はあなたがコンパイル時に言及したスレッドの問題を検出することができますかわからないけど https://www.javacodegeeks.com/2015/09/java-annotation-processors.html

1

GUI Effect Checkerされています。以下はits documentationから取られました:

最も一般的なGUI関連のバグの1つは無効なUIアップデートまたは無効なスレッドアクセスです。バックグラウンドスレッドから直接UIにアクセスしています。

GUIエフェクトチェッカーはこの問題を解決します。 GUIエフェクトチェッカーは、UIスレッドのみがUIオブジェクトにアクセスすることを保証します。これにより、無効なUIの更新や無効なスレッドアクセスなどのGUIエラーを防ぐことができます。

プログラマかどうかを示すために、各メソッド注釈:それがUI要素にアクセスしない(及び任意のスレッドで実行することができる)

  • と、そのような方法は「安全な効果」を有すると言われている。
  • UI要素にアクセスすることができます(UIスレッドで実行する必要があります)。そのような方法は「UI効果」を有すると言われている。

コンパイル時に、GUI効果チェッカーは、次の場合にエラーを発行します。

  • A @UIEffect方法は@SafeEffectメソッドによって呼び出されます。
  • メソッドの宣言はサブタイプの制限に違反します。スーパータイプは@SafeEffectメソッドを宣言し、サブタイプは@UIEffectとしてオーバーライドするバージョンを注釈します。
関連する問題