Handler分析
2019-10-25 本文已影响0人
gaga丶
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//主线程更新ui 线程之间的通讯
}
};
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//子线程发送消息
Message message=Message.obtain();
message.obj="Handler Test";
mHandler.sendMessage(message);
}
}).start();
为什么使用Message.obtain()而不是new Message();
查看是否有回收的消息,如果有回收消息就使用回收的消息,不用再去创建Message;
1、sendMessage
mHandler.sendMessage(message); ——> sendMessageDelayed ——>
sendMessageAtTime ——> enqueueMessage(MessageQueue queue, Message msg, long
uptimeMillis)
enqueueMessage:消息队列(链表)按when进行排序
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
//死循环
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
2、Loop消息循环
创建handler的时候创建Looper
mLooper = Looper.myLooper();——》return sThreadLocal.get();——》Thread t = Thread.currentThread();
拿到当前的线程
一个Handler中只有一个Looper,子线程中使用Handler必须先调用Looper.prepare();不然会报错,我们在主线程中并没有调用过 Looper.prepare,为什么不报错?
主线程不用 Looper.prepare
因为我们在应用启动的时候,ActivityThread的入口函数 main()方法中已经帮我们写了这行代码
Looper.prepareMainLooper //准备循环
sThreadLocal.set(new Looper(quitAllowed));
Thread t = Thread.currentThread();
//从线程中获取ThreadLocalMap
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
总结:其实就是创建一个Looper,并且保证一个Thread线程中,只有一个Looper对象
Looper.loop //循环
public static void loop() {
//获取线程的Looper对象
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
//获取队列
final MessageQueue queue = me.mQueue;
for (;;) {
//死循环不断获取消息队列中的消息
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
try {
//通过Handler去执行essage,这个时候就调用了handlerMessage方法
//msg.target是当前handler 再handler。sendMessage()方法中 msg.target=this;
msg.target.dispatchMessage(msg);
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
//回收消息
msg.recycleUnchecked();
}
}