Table of Contents

Handlers and Messaging

Passing a message to a function in another class

Function will process message in handler thread, not the main thread

// first we create the class and implement the callback interface
public class GetMessageClass implements Handler.Callback {
 
    @Override
    public boolean handleMessage(@NonNull Message msg) {
        // parse the message using the message key
        Bundle bundle = msg.getData();
        String string = bundle.getString("mykey");
        Log.v("javademo3","got the message: " + string);
        return false;
    }
}

Then in the main activity:

public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // after we have a class with a callback, we create a thread for the handler.
        // every handler has a looper which actually calls the handler:
        HandlerThread handlerThread = new HandlerThread("myHandlerThread");
        handlerThread.start();
        Looper looper = handlerThread.getLooper();
        // create an instance of the class
        GetMessageClass getMessageClass = new GetMessageClass();
        // create a new handler and assign it to the looper in the handler thread
        Handler handler = new Handler(looper, getMessageClass);
 
        // boilerplate to send a message
        Message msg = handler.obtainMessage(); // ?
        Bundle bundle = new Bundle();
        bundle.putString("mykey", "hello");
        msg.setData(bundle);
        handler.sendMessage(msg);
    }
}

Pass message then receive back from the other class

// first we create the class and implement the callback interface
public class GetMessageClass implements Handler.Callback {
 
    Handler handler; // get the mainUI handler for messaging back
 
    public GetMessageClass(Handler h) {
        handler = h;
    }
 
    @Override
    public boolean handleMessage(@NonNull Message msg) {
        // parse the message using the message key
        Bundle bundle = msg.getData();
        String string = bundle.getString("mykey");
        Log.v("javademo3","got the message: " + string);
 
        // boilerplate to send a message back
        Message msg2 = handler.obtainMessage(); // ?
        Bundle bundle2 = new Bundle();
        bundle2.putString("mykey2", "pong");
        msg2.setData(bundle2);
        handler.sendMessage(msg2);
        return false;
    }
}

and in the main activity:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // after we have a class with a callback, we create a thread for the handler.
        // every handler has a looper which actually calls the handler:
        HandlerThread handlerThread = new HandlerThread("myHandlerThread");
        handlerThread.start();
        Looper looper = handlerThread.getLooper();
 
        // if you want to send a message back to the main activity in the main thread
        // create a handler for it in the main thread and put the function inside the handler:
        Handler mainThreadHandler = new Handler(getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                Bundle bundle = msg.getData();
                Log.v("javademo3", "Got this message back: " + bundle.getString("mykey2"));
            }
        };
 
        // create an instance of the class and pass the main thread handler to it for messaging back
        GetMessageClass getMessageClass = new GetMessageClass(mainThreadHandler);
        // create a new handler and assign it to the looper in the handler thread
        Handler handler = new Handler(looper, getMessageClass);
 
        // boilerplate to send a message
        Message msg = handler.obtainMessage(); // ?
        Bundle bundle = new Bundle();
        bundle.putString("mykey", "ping");
        msg.setData(bundle);
        handler.sendMessage(msg);
    }
 

There are examples as yet unexplored of handlers posting runnables. For example, this sort of thing should work according to my brain and not tested by a living breathing compiler:

handler.post(new Runnable() {
                        @Override
                        public void run() {
                            Log.v("someCrazyCode","I got here");
                        }
                    });

Resources

* https://medium.com/mindorks/mastering-android-handler-4f710296bdc6