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
Looper
runs a message loop on a thread using theMessageQueue
MessageQueue
holds a list of messages to be dispatched by theLooper
Handler
allows the sending and processing ofMessage
andRunnable
to theMessageQueue
.Message
contains a description and data that can be sent to a handlerRunnable
represents a task to be executed.
Class Diagram
Notes:
- UI thread has a
looper
by 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
Handler
is theMessage
producer- Sending
Message
or postRunnable
(task message) objects to theMessageQueue
that associated with aThread
- Receives the objects from the
Looper
and 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
Looper
isMessage
consumerLooper
keeps the thread alive while it waits to receive more tasks- A thread can have only one
Looper
and 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
Handler
class and overridehandleMessage
method - 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