Android:调用Remote Messenger Service时同步方法

时间:2012-04-19 22:48:36

标签: android handler synchronous messenger

我想编写一个连接远程服务的模块。

开发人员可以在他们的应用程序中使用该模块连接到特定的(蓝牙)硬件。然后它应该连接到一个可以在市场上单独更新的远程服务。

因为远程服务只允许同时使用它的所有应用程序都有一个线程(只有一个蓝牙连接),所以我选择了信使方法而不是AIDL。

我现在的问题是我想在我的公共API中提供一个同步方法,但服务在处理程序中返回 - 据我所知,处理程序将总是等待当前任务完成...所以有没有办法在不同的线程中得到答案?

我想要的同步方法的代码:

responseDataSync = new Sync<ResponseData>();

    // Send message
    Message msg = Message.obtain(null, Constants.DATA, 1, 0);

    send(msg);

    try {
        ResponseData responseData = responseDataSync.get();

        // with responseDataSync using a countdown latch to synchronize...
// but it never fires thanks to the handler.
//etc...

提前致谢。我希望我的问题有点可以理解......;)

/编辑: 我想要一些从服务器返回数据的方法。像

 public ResponseData returnResponse(Data dataToSend)

但是我不能等待服务的返回,因为那时我被困在线程中阻止处理程序返回...

1 个答案:

答案 0 :(得分:3)

Handler与单个邮件队列相关联。如果您从任何线程发送Message,它将在那里排队。

接收所有消息的线程将从队列中获取相应的消息并逐个处理它。

对你来说,如果你有一个处理程序,并且通过你的处理程序运行所有消息,则不需要同步,因为所有内容都在一个线程中处理。

编辑:创建处理后台线程中的消息的处理程序:

HandlerThread ht = new HandlerThread("threadName");
ht.start();
Looper looper = ht.getLooper();
Handler.Callback callback = new Handler.Callback() {

    @Override
    public boolean handleMessage(Message msg) {
        // handled messages are handled in background thread 
        return true;
    }
};
Handler handler = new Handler(looper, callback);

handler.sendEmptyMessage(1337);

Edit2:等待消息可能会像这样工作

// available for all threads somehow
final Object waitOnMe = new Object();

HandlerThread ht = new HandlerThread("threadName");
ht.start();
Looper looper = ht.getLooper();
Handler.Callback callback = new Handler.Callback() {

    @Override
    public boolean handleMessage(Message msg) {
        // handled messages are handled in background thread
        // then notify about finished message.
        synchronized (waitOnMe) {
            waitOnMe.notifyAll();
        }
        return true;
    }
};
Handler handler = new Handler(looper, callback);

// in a different Thread:
synchronized (waitOnMe) {
    handler.sendEmptyMessage(1337);
    try {
        waitOnMe.wait();
    } catch (InterruptedException e) {
        // we should have gotten our answer now.
    }
}