0

正如标题所说,我正在寻找一种优雅的方式来实现 Android 中线程之间的通用异步请求/响应机制。

我需要能够:

  • 使用不同类型的参数异步向另一个对象发送请求
  • 通过将响应发布到发送者的队列,让该对象可选择地异步响应

假设我有扩展线程的管理器类型的对象。每个这样的 Manager 都有一个 Handler 和一个 Looper,这样它们就可以异步地将消息推送到彼此的队列中。

简单地说,在伪代码中,我会像这样实现它:

Manager extends Thread
{
    // loop forever, pulling a request from the queue and handling it
    listenToRequests()
    {
        Looper.prepare()
        m_handler = new Handler()
        {
            handleMessage(msg)
            {
                switch(msg.what)
                {
                    case REQUEST_TYPE_0:
                        handleRequestType0(msg.object, msg.args);
                        break;

                    case REQUEST_TYPE_1:
                        handleRequestType1(msg.object, msg.args);
                        break;

                    ...
                }
            }
        }
    }

其他管理器实例需要分配一条消息,填充它并将其发送到目标管理器:

msg = targetManager.getHandler().obtainMessage();
    msg.what = REQUEST_TYPE_0;
    msg.object = this;
    msg.args = ...;

msg.sendToTarget();

然后目标管理器可以在发送者上获取Message(),填充响应消息并发送它。

上面代码的问题在于,虽然它确实满足了这两个要求,但对于每条消息都有很多烦人的样板代码需要实现:

  • 在某些枚举中定义消息类型(例如 REQUEST_TYPE_N)
  • 将大量参数放入消息中,以便对它们进行编组
  • 添加一个 switch case 来调度消息并处理它

使用 Runnable 确实解决了打包参数和消除消息调度的问题(通过 switch/case):

public void doRequest0(args)
{
    handler.post(new Runnable() 
    {
        @Override
        public void run() 
        {
            // do stuff with args...

            args.sender.request0Response(...);
        }
     });
}

这样做的问题是,代替回调,我必须声明和实现响应接口。在每个这样的接口函数中,我都必须用 handler.post(new Runnable() ... 进行装饰,这似乎也是很多样板代码。

我还有其他选择吗?看起来我的要求很谦虚,但我的解决方案在语法上过于复杂。

4

0 回答 0