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