Android Concurrent Programming: HaMeR framework - Tuong-Nguyen/Android GitHub Wiki
What is HaMeR?
The HaMeR framework allows background threads to send messages or post runnables to UI thread and any other thread's MessageQueue via handlers.
HaMeR refers to Handler, Message and Runnable
Mechanism
Looperruns a message loop on a thread using theMessageQueueMessageQueueholds a list of messages to be dispatched by theLooperHandlerallows the sending and processing ofMessageandRunnableto theMessageQueue.Messagecontains a description and data that can be sent to a handlerRunnablerepresents a task to be executed.
Class Diagram
Notes:
- UI thread has a
looperby default.- If the thread does not have a
looper, this handler won't be able to receive messages so an exception is thrown.
Handler Class
Handleris theMessageproducer- Sending
Messageor postRunnable(task message) objects to theMessageQueuethat associated with aThread - Receives the objects from the
Looperand processes the messages.
Instantiating a Handler
// Handler uses current Thread's Looper
Handler handler = new Handler();
// Handler uses the Looper provides
Handler handler = new Handler(Looper);
Looper and MessageQueue
LooperisMessageconsumerLooperkeeps the thread alive while it waits to receive more tasks- A thread can have only one
Looperand oneMessageQueue Looper's thread can associate with multipleHandler
Preparing a Thread
UI thread or main thread already has a Handler, a Looper and a MessageQueue by default.
Other threads must be prepared, we can do this as follows:
// Preparing a Thread for HaMeR
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
// adding and preparing the Looper
Looper.prepare();
// the Handler instance will be associated with Thread’s Looper
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
// Starting the message queue loop using the Looper
Looper.loop();
}
}
or use HandlerThread class
// The HandlerThread class includes a working Looper
public class HamerThread extends HandlerThread {
// you just need to add the Handler
private Handler handler;
public HamerThread(String name) {
super(name);
}
}
Handling Messages with Handler
The Message objects dispatched by Looper are processed by the handler with the method Handler.handleMessage
public class MessageHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
// handle 'Hello' msg
case 0:{
String hello = (String) msg.obj;
System.out.println(hello);
break;
}
}
}
}
Conclusion
In Android, if we want to achieve concurrent behavior, we need:
- A handler by extending
Handlerclass and overridehandleMessagemethod - Create a client (can be a service) that has association with the handler so that we can produce a message by
handler.sendMessage(Message) - An Activity that has association with the handler so that the handler can access the UI.
Ref:
http://pierrchen.blogspot.com/2015/08/android-concurrent-programming-looper.html
https://code.tutsplus.com/tutorials/concurrency-on-android-using-hamer-framework--cms-27129