前言
原理性的东西大家都很熟悉了,这里就不老生常谈了,主要是最近一位朋友面试遇到了此要求,希望我能帮他写出来,所以我简单地根据源码撸了大概的样子出来,流程基本有,主要是创建Looper,里面在创建维护着一个MessageQueen,再把Looper存入ThreadLocal,创建Handler,sendMssage的时候把这个Message的Target设置为当前Handler,然后把Message压入MessageQueen,最后开启Looper循环从MessageQueen获取Message然后从Target取出Handler交由其HandlerMessage处理。
MyHandler
public class MyHandler {
private String instance;
public Callback callback;
private MyLooper myLooper;
public interface Callback {
public boolean handleMessage(MyMessage msg);
}
public MyHandler(String instance, Callback callback) {
this.instance = instance;
this.callback = callback;
this.myLooper = MyLooper.myLooper();
;
}
public void sendMyMessage(MyMessage myMessage) {
if (myMessage != null) {
myMessage.setTarget(this);
}
System.out.println("消息进队列:" + instance);
myLooper.queueMessage(myMessage);
}
@Override
public String toString() {
return instance;
}
}
private String instance;
public Callback callback;
private MyLooper myLooper;
public interface Callback {
public boolean handleMessage(MyMessage msg);
}
public MyHandler(String instance, Callback callback) {
this.instance = instance;
this.callback = callback;
this.myLooper = MyLooper.myLooper();
;
}
public void sendMyMessage(MyMessage myMessage) {
if (myMessage != null) {
myMessage.setTarget(this);
}
System.out.println("消息进队列:" + instance);
myLooper.queueMessage(myMessage);
}
@Override
public String toString() {
return instance;
}
}
MyLooper
public class MyLooper {
private MyMessageQueue myMessageQueue;
static final ThreadLocal<MyLooper> sThreadLocal = new ThreadLocal<MyLooper>();
private MyLooper() {
myMessageQueue = MyMessageQueue.getInstance();
}
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 void loop() {
final MyLooper me = myLooper();
for (;;) {
MyMessage msg = me.myMessageQueue.next();
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
if (msg != null) {
msg.getTarget().callback.handleMessage(msg);
}
}
}
public static MyLooper myLooper() {
return sThreadLocal.get();
}
public void queueMessage(MyMessage myMessage) {
try {
myMessageQueue.produce(myMessage);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private MyMessageQueue myMessageQueue;
static final ThreadLocal<MyLooper> sThreadLocal = new ThreadLocal<MyLooper>();
private MyLooper() {
myMessageQueue = MyMessageQueue.getInstance();
}
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 void loop() {
final MyLooper me = myLooper();
for (;;) {
MyMessage msg = me.myMessageQueue.next();
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
if (msg != null) {
msg.getTarget().callback.handleMessage(msg);
}
}
}
public static MyLooper myLooper() {
return sThreadLocal.get();
}
public void queueMessage(MyMessage myMessage) {
try {
myMessageQueue.produce(myMessage);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MyMessage
public class MyMessage {
private MyHandler target;
private String what;
public MyMessage(String what) {
this.what = what;
}
public String getWhat() {
return what;
}
public void setWhat(String what) {
this.what = what;
}
public MyHandler getTarget() {
return target;
}
public void setTarget(MyHandler target) {
this.target = target;
}
}
private MyHandler target;
private String what;
public MyMessage(String what) {
this.what = what;
}
public String getWhat() {
return what;
}
public void setWhat(String what) {
this.what = what;
}
public MyHandler getTarget() {
return target;
}
public void setTarget(MyHandler target) {
this.target = target;
}
}
MyMessageQueue
public class MyMessageQueue {
private LinkedBlockingQueue<MyMessage> linkedBlockingQueue = new LinkedBlockingQueue<MyMessage>();
private static MyMessageQueue instance;
private MyMessageQueue() {
}
public static synchronized MyMessageQueue getInstance() {
if (instance == null) {
instance = new MyMessageQueue();
}
return instance;
}
public void produce(MyMessage myMessage) throws InterruptedException {
linkedBlockingQueue.put(myMessage);
}
public MyMessage consume() throws InterruptedException {
return linkedBlockingQueue.take();
}
public MyMessage next() {
MyMessage msg = null;
try {
msg = consume();
} catch (InterruptedException ex) {
System.out.println("MyLooper Interrupted");
}
return msg;
}
}
private LinkedBlockingQueue<MyMessage> linkedBlockingQueue = new LinkedBlockingQueue<MyMessage>();
private static MyMessageQueue instance;
private MyMessageQueue() {
}
public static synchronized MyMessageQueue getInstance() {
if (instance == null) {
instance = new MyMessageQueue();
}
return instance;
}
public void produce(MyMessage myMessage) throws InterruptedException {
linkedBlockingQueue.put(myMessage);
}
public MyMessage consume() throws InterruptedException {
return linkedBlockingQueue.take();
}
public MyMessage next() {
MyMessage msg = null;
try {
msg = consume();
} catch (InterruptedException ex) {
System.out.println("MyLooper Interrupted");
}
return msg;
}
}
Test
public class Test {
public static void main(String[] args) {
MyLooper.prepare();
final MyHandler myHandler1 = new MyHandler("firsthandler",new MyHandler.Callback() {
public boolean handleMessage(MyMessage msg) {
System.out.println(msg.getTarget().toString()+msg.getWhat());
return false;
}
});
final MyHandler myHandler2 = new MyHandler("secondhandler", new MyHandler.Callback() {
public boolean handleMessage(MyMessage msg) {
System.out.println(msg.getTarget().toString()+msg.getWhat());
return false;
}
});
new Thread(new Runnable() {
public void run() {
MyMessage myMessage = new MyMessage("这是第一个handler的消息");
myHandler1.sendMyMessage(myMessage);
MyMessage myMessage1 = new MyMessage("这是第一个handler的消息");
myHandler1.sendMyMessage(myMessage1);
}
}).start();
new Thread(new Runnable() {
public void run() {
MyMessage myMessage = new MyMessage("这是第二个handler的消息");
myHandler2.sendMyMessage(myMessage);
}
}).start();
MyLooper.loop();
}
}
public static void main(String[] args) {
MyLooper.prepare();
final MyHandler myHandler1 = new MyHandler("firsthandler",new MyHandler.Callback() {
public boolean handleMessage(MyMessage msg) {
System.out.println(msg.getTarget().toString()+msg.getWhat());
return false;
}
});
final MyHandler myHandler2 = new MyHandler("secondhandler", new MyHandler.Callback() {
public boolean handleMessage(MyMessage msg) {
System.out.println(msg.getTarget().toString()+msg.getWhat());
return false;
}
});
new Thread(new Runnable() {
public void run() {
MyMessage myMessage = new MyMessage("这是第一个handler的消息");
myHandler1.sendMyMessage(myMessage);
MyMessage myMessage1 = new MyMessage("这是第一个handler的消息");
myHandler1.sendMyMessage(myMessage1);
}
}).start();
new Thread(new Runnable() {
public void run() {
MyMessage myMessage = new MyMessage("这是第二个handler的消息");
myHandler2.sendMyMessage(myMessage);
}
}).start();
MyLooper.loop();
}
}