在android的消息机制中,Message其充当着信息载体的一个角色,通俗的来说,我们看作消息机制就是个工厂的流水线,message就是流水线上的产品,messageQueue就是流水线的传送带。之前做面试官的时候,经常会问面试者关于message的问题,如:
1.聊一下你对Message的了解。
2.如何获取message对象
3.message的复用(如果以上问题能答对,加分)
在下面我带着这三个问题,从这段代码开始逐一解析。
/**
* 创建一个handler
*/
Handler handler = new Handler();
/**
* 模拟开始
*/
private void doSth() {
//开启个线程,处理复杂的业务业务
new Thread(new Runnable() {
@Override
public void run() {
//模拟很复杂的业务,需要1000ms进行操作的业务
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
//在这里可以更新ui
mTv.setText("在这个点我更新了:" + System.currentTimeMillis());
}
});
}
}).start();
}
我们创建了一个handler,在doSth()中开启线程模拟处理复杂业务,最后通过handler的post返回结果进行UI操作(子线程不能进行操作UI,后话),我们先从handler的post开始看起,
Handler.java:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* @param r The Runnable that will be executed.
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean post(Runnable r) {
//通过getPostMessage获取了message,再往下看
return sendMessageDelayed(getPostMessage(r), 0);
}
在post中,我们传进一个Runnable参数,我们发现有一个getPostMessage(r)函数,我们先从getPostMessage()下手。
Handler.java:
private static Message getPostMessage(Runnable r) {
//在这里,获取一个message,把我们的任务封装进message
Message m = Message.obtain();
m.callback = r;
return m;
}
从getPostMessage函数可得,我们把参数Runnable封装进去message的callback变量中,在这里埋伏一个很重要的概念,在Handler的源码中,是如何获取message对象的。顾名思义,在getPostMessage中,我们就是为了获取把runnable封装好的message。这样,我们可以返回上一层,继续看函数sendMessageDelayed(Message,long)。
Handler.java:
/**
* Enqueue a message into the message queue after all pending messages
* before (current time + delayMillis). You will receive it in
* {@link #handleMessage}, in the thread attached to this handler.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the message will be processed -- if
*