Question

I want to write a module that connects to a remote Service.

The module can be used by developers in their apps to connect to a specific (bluetooth-)hardware. It should then connect to a single remoteservice that can be updated seperately in the market.

Because the Remote Service is only allowed to have a single thread for all the apps using it at the same time (Only one connection over bluetooth), I have chosen the messenger approach over AIDL.

My problem is now that I wanted to provide a synchronous method in my public API but the service returns in an handler - and as far as I have understood, the handler will allways wait for the current task to finish... So is there any way to get the answer in a differen thread?

the code of the synchronous method as I would like it to be:

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...

Thanks in advance. I hope my question was somewhat understandable... ;)

/EDIT: I want some method that returns data from the server. like

 public ResponseData returnResponse(Data dataToSend)

but I can't wait for the service's return because then I am stuck in the thread what blocks the handler from returning...

Was it helpful?

Solution

A Handler is associated with a single message queue. If you send a Message from any Thread it will get enqueued there.

The Thread that receives all the Messages will get the appropriate message off the queue and handle it - one by one.

Meaning for you that if you have a Handler and you run all Messages through you handler you don't need synchronization since everything is handled in a single thread.

Edit: to create a Handler that handles messages in a background thread:

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: wait on Messages might work like this

// 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.
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top