4

When you implement a Runnable which uses a Handler and Looper, you end up with a blocking queue for the Messages/Runnables within the run() method of your Runnable, because the loop() method blocks.

Like this:

public class Task1 implements Runnable {
    private Handler mHandler;
    private boolean mCancelled = false;

    private void init() {
        Looper.prepare();
        mHandler = new Handler() {
           public void handleMessage(Message msg) {
              // process incoming messages here
           }
        };
        Looper.loop();
    }

    @Override
    public void run() {
        init();

        while (!mCancelled) {
           try {
              // do stuff here
              TimeUnit.SECONDS.sleep(2);
           } catch (InterruptedException e) {
              // handle exception here
              e.printStackTrace();
           }
        }
    }

    public void cancel() {
        mCancelled = true;
        Looper.quit();
    }
}

In the implementation of Looper.class you see that the queue that is being used makes a call to queue.next() which can BLOCK the running thread.

public static void loop() {
    // ...
    for (;;) {
        Message msg = queue.next(); // might block
        // ...
    }
}

This is NOT what I want. I want to be able to use the runnable task to communicate with a handler (send and receive Messages) but also do the actual work within the run() method, for example Bluetooth communications. When you call the connect() method of a BluetoothSocket, this call blocks the current thread until a connection is made. (See BluetoothSocket.connect() for details. So this means I have a blocking thread as long as no connection is made. There is nothing to communicate without an established connection, so that is good. After the connection is established, I would like to exchange messages. If the thread/runnable gets cancelled, it also quit the Looper/Handler.

Now my question is: how do I use a Looper/Handler within a Runnable and not let the Looper block the Runnable so that the normal code can be executed instead? I only want to receive Messages through the Handler, not Runnables!

Thanks for your kind help.

Edit: too bad the Looper doesn't have a function like the BlockingQueue interface does, like take() instead of next(), which is blocking.

user504342
  • 945
  • 2
  • 16
  • 36

0 Answers0