2016-06-23 5 views
0

私は、この私のプロジェクトでasyncronus XML-RPCクライアント(https://github.com/gturri/aXMLRPC)を使用し、このように、このクライアントのasyncronousコールバック・メソッドを使用して、いくつかの方法を書いている:私が好きな他の方法でコールバック応答からメソッドを呼び出すベストプラクティスは?

public void xmlRpcMethod(final Object callbackSync) { 
    XMLRPCCallback listener = new XMLRPCCallback() { 
     public void onResponse(long id, final Object result) { 
      // Do something 
      if (callbackSync != null) { 
       synchronized (callbackSync) { 
        callbackSync.notify(); 
       } 
      } 
     } 

     public void onError(long id, final XMLRPCException error) { 
      // Do something 
      if (callbackSync != null) { 
       synchronized (callbackSync) { 
        callbackSync.notify(); 
       } 
      } 
     } 

     public void onServerError(long id, final XMLRPCServerException error) { 
      Log.e(TAG, error.getMessage()); 
      if (callbackSync != null) { 
       synchronized (callbackSync) { 
        callbackSync.notifyAll(); 
       } 
      } 
     } 
    }; 

    XMLRPCClient client = new XMLRPCClient("<url>"); 
    long id = client.callAsync(listener, "<method>"); 

} 

呼び出すためにこのメソッド(ここでは "xmlRpcMethod")を呼び出し、終了するまで待機します。

public void testMethod(){ 
    Object sync = new Object(); 
    xmlRpcMethod(sync); 
    synchronized (sync){ 
     try{ 
      sync.wait(); 
     }catch(Interrupted Exception e){ 
      e.printStackTrace(); 
     } 
    } 
    // Do something after xmlRcpFinished 
} 

しかし、待っていると、プロジェクトが大きくなると、私は終了する多くの要求を待つ必要がある場合の醜いを取得同期させるこの方法:私はこのような方法を書きました。 これは唯一可能な/最良の方法ですか?あるいは誰かがより良い解決策を知っていますか? RPCコールを遮断作成する

+0

FuturesとExecutorServiceについて聞いたことがありますか?あなたはコンカレントコレクションでもそれを行うことができます。 – Fildor

+0

先物はかなり面白いようです!これらのヒントをありがとう! – bartolja

答えて

0

私の最初のショットは、次のようになります。

// Little helper class: 
class RPCResult<T>{ 
    private final T result; 
    private final Exception ex; 
    private final long id; 

    public RPCResult(long id, T result, Exception ex){ 
     // TODO set fields 
    } 

    // TODO getters 

    public boolean hasError(){ return null != this.ex; } 
} 


public Object xmlRpcMethod() { 
    final BlockingQueue<RPCResult> pipe = new ArrayBlockingQueue<RPCResult>(1); 
    XMLRPCCallback listener = new XMLRPCCallback() { 
     public void onResponse(long id, final Object result) { 
      // Do something 
      pipe.put(new RPCResult<Object>(id, result, null)); 
     } 

     public void onError(long id, final XMLRPCException error) { 
      // Do something 
      pipe.put(new RPCResult<Object>(id, null, error)); 
     } 

     public void onServerError(long id, final XMLRPCServerException error) { 
      Log.e(TAG, error.getMessage()); 
      pipe.put(new RPCResult<Object>(id, null, error)); 
     } 
    }; 

    XMLRPCClient client = new XMLRPCClient("<url>"); 
    long id = client.callAsync(listener, "<method>"); 
    RPCResult result = pipe.take(); // blocks until there is an element available 
    // TODO: catch and handle InterruptedException! 
    if(result.hasError()) throw result.getError(); // Relay Exceptions - do not swallow them! 
    return result.getResult(); 
} 

クライアント:

public void testMethod(){ 
    Object result = xmlRpcMethod(); // blocks until result is available or throws exception 
} 

次のステップは、強く型付けされたバージョンpublic T xmlRpcMethod()を作ることであろう。

+0

これはありがとう、それは本当にクライアントメソッドで使いやすいように見える - 非常に素晴らしい!ほとんどの場合、私は呼び出し元のメソッドに応答を戻す必要はありません。呼び出し側は、応答が受信され、リスナーのonResponseメソッドによって処理されるまで待機する必要があります。したがって、xmlRpcMethodはほとんどの場合無効になり、入力は不要です。 – bartolja

+0

その場合は、単に結果を無視することができます。しかし、それはブロックが発生する場所であるため、キューからフェッチする必要があります。私は例外があればそれを投げます。 – Fildor

+0

'take 'は永遠に" take "するかもしれませんが、' poll'を使うとタイムアウト機能を導入することができます。必要ないかもしれませんが、私はそれに言及すると思った。 – Fildor

関連する問題