Search code examples
androidmultithreadinghandlerrunnableandroid-handlerthread

How to use a HandlerThread to juggle 2 Threads


I have a class that extends HandlerThread and implements Handler.Callback. I can't understand how to setup the Handlers to send messages back and forth to each other under this scheme. My Handler1 needs to talk to Handler2 and vice versa but because this is being implemented in a HandlerThread which has it's own looper I am not sure how to instantiate these objects. I'm simply stuck on how to apply this to syntax. I have posted my crack at it below. Any help is appreciated.

...
public class MyClass implements Runnable {

private Handler handler1 = null;
private Handler handler2 = null;

CyclicBarrier barrier = new CyclicBarrier(2);

class myThread extends HandlerThread implements Handler.Callback {

    ...

    @Override    
    protected void onLooperPrepared() {

        handler1 = new Handler(getLooper(), this){

            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
            }

        };
        handler2 = new Handler(getLooper(), this){

            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
            }

        };

        try {
            barrier.await();
        } catch (Exception e) {
            e.printStackTrace();
        }

        Runnable runnable1 = new Runnable(){

            @Override
            public void run() {

                Message message = Message.obtain();
                message.setTarget(handler2);
                message.obj = handler2;
                message.sendToTarget();

            }               
        };
        Runnable runnable2 = new Runnable(){

            @Override
            public void run() {

                Message message = Message.obtain();
                message.obj = handler1;
                message.setTarget(handler1);

            }               
        };
    }

    @Override
    public boolean handleMessage(Message reqMsg) {

        //do some work

        return true;
    }
}

...

public void run() {

    Thread mThread1 = new Thread(runnable1);
    Thread mThread2 = new Thread(runnable2);

    mThread1.start();
    mThread2.start();
}

}


Solution

  • Here is the refactored code:

    public class MyClass implements Runnable
    

    {

    private Handler handler1 = null;
    private Handler handler2 = null;
    
    CyclicBarrier barrier = new CyclicBarrier(2);
    
    class myThread extends HandlerThread implements Handler.Callback
    {
    
      public myThread(String sName)
      {
        super(sName);
      }
    
      @Override
      protected void onLooperPrepared() {
    
        handler1 = new Handler(getLooper(), this){
    
          @Override
          public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
          }
    
        };
        handler2 = new Handler(getLooper(), this){
    
          @Override
          public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
          }
    
        };
    
        try {
          barrier.await();
        } catch (Exception e) {
          e.printStackTrace();
        }
    
    
      }
    
      @Override
      public boolean handleMessage(Message reqMsg) {
    
        //do some work
    
        return true;
      }
    }
    
    Runnable runnable1 = new Runnable(){
    
      @Override
      public void run() {
    
        Message message = Message.obtain();
        message.setTarget(handler2);
        message.obj = handler2;
        message.sendToTarget();
    
      }
    };
    Runnable runnable2 = new Runnable(){
    
      @Override
      public void run() {
    
        Message message = Message.obtain();
        message.obj = handler1;
        message.setTarget(handler1);
    
      }
    }; 
    
    public void run() {
    
      Thread mThread1 = new Thread(runnable1);
      Thread mThread2 = new Thread(runnable2);
    
      mThread1.start();
      mThread2.start();
    }
    

    } }