大佬教程收集整理的这篇文章主要介绍了Handler.post()源码分析,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在分析post源码时候我们先看看message里面是什么
public final class message implements Parcelable {
****public int what;
Runnable callBACk;
**message next;**
Handler target;
**public long when;**
Bundle data;
}
从此看的出message是一个链表的节点,ok看看post
public final Boolean post(@NonNull Runnable r) {
return sendmessageDelayed(getPostmessage(r), 0);
}
public final Boolean postDelayed(@NonNull Runnable r, long delaymillis) {
return sendmessageDelayed(getPostmessage(r), delaymillis);
}
public final Boolean sendmessage(@NonNull message msg) {
return sendmessageDelayed(msg, 0);
}
public final Boolean sendmessageDelayed(@NonNull message msg, long delaymillis) {
if (delaymillis < 0) {
delaymillis = 0;
}
return sendmessageAtTime(msg, SystemClock.uptimeMillis() + delaymillis);
}
public Boolean sendmessageAtTime(@NonNull message msg, long uptimeMillis) {
messageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendmessageAtTime() called with no mQueue");
Log.w("Looper", e.getmessage(), E);
return false;
}
return enqueuemessage(queue, msg, uptimeMillis);
}
private Boolean enqueuemessage(@NonNull messageQueue queue, @NonNull message msg,
long uptimeMillis) {
msg.target = this;
msg.worksourceUid = ThreadLocalWorksource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueuemessage(msg, uptimeMillis);
}
由此可知,不管是post,还是postdelay实际上调用的都是queue的enqueue,uptimeMillis用的是系统时间 + delay的时间,msg是包装出来的message,这个我就不读了,现在看看enqueuemessage
Boolean enqueuemessage(message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentexception("message must have a target.");
}
synchronized (this) {
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
if (mQuitTing) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(tag, e.getmessage(), E);
msg.recycle();
return false;
}
msg.markInUse();
msg.when = 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;**
}
// We can assume mPtr != 0 because mQuitTing is false.
if (needWakE) {
nativeWake(mPtr);
}
}
return true;
}
看看这是什么呀
message p = mmessages;
**msg.next = p;
mmessages = msg;
典型的链表头插法,mmessage为头结点**
if (p == null || when == 0 || when < p.when)
**if (p == null || when < p.when) {
break;
}
寻找when时间小于message.when的节点
大家懂了吧
这就是按照时间降序排序的message的链表啊**
盲猜Looper取message时肯定往时间越小的那,拿尾节点实现,按照时间执行handlemessage啊
现在我们看看Looper.loop()是怎么拿东西的
public static void loop() {
message msg = queue.next();
for (;;) {
....
message msg = queue.next(); // might block
if (msg == null) {
// No message inDicates that the message queue is quitTing.
return;
}
.....
msg.target.dispatchmessage(msg);
.....
msg.recycleUn@R_197_10943@ked();
}
}
现在我们去看看queue.next() 看看是不是我说的那样
message next() {
........
**message prevMsg = null;
message msg = mmessages;**
if (msg != null && msg.target == null) {
// Stalled by a barrier. Find the next asynchronous message in the queue.
do {
prevMsg = msg;
msg = msg.next;
} **while (msg != null && !msg.isAsynchronous());**
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.max_value);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mmessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(tag, "Returning message: " + msg);
msg.markInUse();
**return msg;**
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
// Process the quit message now that all pending messages have been handled.
if (mQuitTing) {
dispose();
return null;
}
.......
}
看到了吧 ,从头开始遍历,一直到取尾巴节点
以上是大佬教程为你收集整理的Handler.post()源码分析全部内容,希望文章能够帮你解决Handler.post()源码分析所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。