handler消息机制
MyLooper
public class MyLooper {
static final ThreadLocal<MyLooper> sThreadLocal = new ThreadLocal<>();
public MyMessageQueue myQueue;
public MyLooper(){
myQueue = new MyMessageQueue();
}
public static void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new MyLooper());
}
public static MyLooper myLooper() {
return sThreadLocal.get();
}
public static void loop() {
// 从全局ThreadLocalMap中获取唯一looper对象
MyLooper myLooper = myLooper();
MyMessageQueue myQueue = myLooper.myQueue;
while (true) {
MyMessage myMessage = myQueue.next();
if (myMessage != null) {
myMessage.target.dispatchMessage(myMessage);
}
}
}
}
MyMessageQueue
public class MyMessageQueue {
// 阻塞队列
BlockingQueue<MyMessage> myMessages = new ArrayBlockingQueue<>(50);
public MyMessageQueue() {
}
public void enqueueMessage(MyMessage message) {
try {
myMessages.put(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 从消息队列中取出
public MyMessage next() {
try {
return myMessages.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
MyMessage
public class MyMessage {
Object obj;
int what;
MyHandler target;
}
MyHandler
public class MyHandler {
private MyLooper myLooper;
private MyMessageQueue myQueue;
public MyHandler() {
myLooper = MyLooper.myLooper();
if (myLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
myQueue = myLooper.myQueue;
}
public void handleMessage(MyMessage msg) {
}
public void sendMessage(MyMessage message) {
message.target = this;
// 将消息放入到消息队列中
myQueue.enqueueMessage(message);
}
public void dispatchMessage(MyMessage myMessage) {
handleMessage(myMessage);
}
}
main
@Test
public void handlerMain() {
MyLooper.prepare();
final MyHandler handler = new MyHandler(){
@Override
public void handleMessage(MyMessage msg) {
super.handleMessage(msg);
System.out.println(msg.obj.toString());
}
};
new Thread(new Runnable() {
@Override
public void run() {
MyMessage message = new MyMessage();
message.obj = "消息";
handler.sendMessage(message);
}
}).start();
MyLooper.loop();
}
运行结果
Thread, Handler, Looper, MessageQueue对应关系
安卓中一个线程只能初始化一次Looper对象,一个Looper对象中持有一个MessageQueue对象。所以Thread, Looper, MessageQueue是一对一关系。而Handler只是持有当前线程中Looper的引用。