【问题标题】:Whats the Best Practice to call a method out of a Callback-Response?从回调响应中调用方法的最佳实践是什么?
【发布时间】:2016-06-23 18:58:18
【问题描述】:

我在我的项目中使用异步 XML-RPC-Client (https://github.com/gturri/aXMLRPC),并使用此客户端的异步回调方法编写了一些方法,如下所示:

 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
}

但是当项目变得更大并且我需要等待许多请求完成时,这种等待和同步的方式变得很丑陋。 那么这是唯一可能/最好的方法吗?或者有人知道更好的解决方案吗?

【问题讨论】:

  • 你听说过 Futures 和 ExecutorService 吗?你甚至可以使用并发集合来做到这一点。
  • 期货似乎很有趣!感谢这些提示!

标签: java asynchronous callback synchronization asynccallback


【解决方案1】:

我创建阻塞 RPC 调用的第一枪是:

// 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()

【讨论】:

  • 感谢您,它在客户端方法中看起来非常容易使用 - 非常好!在大多数情况下,我不需要将响应返回给调用方法。调用者只需要等待,直到监听器的 onResponse-Method 接收并处理(?)响应。因此 xmlRpcMethod 在大多数情况下也可以是无效的,并且不需要输入。
  • 好的,在这种情况下,您可以简单地忽略结果。但是您必须从队列中获取它,因为这是阻塞发生的地方。如果存在,我会抛出异常。
  • 请注意,take 可能会永远“占用”...poll 您可以引入超时功能。可能没有必要,但我想我会提到它。
  • 是的,我已经知道了,但还是谢谢你!我已经在我的项目中应用了它,并且效果很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多