其他
用了这么多年的Handler,你知道还有个同步屏障的概念吗?
https://juejin.cn/user/3931509313252552
boolean enqueueMessage(Message msg, long when) {
// Hanlder不允许为空
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
...
}
synchronized (this) {
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.markInUse();
msg.when = when;
msg.arg1 = token;
Message prev = null;
Message p = mMessages;
// 把当前需要执行的Message全部执行
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
// 插入同步屏障
if (prev != null) {
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;
}
}
···
if (msg != null && msg.target == null) {
// 同步屏障,找到下一个异步消息
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
···
}
...
// 阻塞时间
int nextPollTimeoutMillis = 0;
for (;;) {
// 阻塞对应时间
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
// 同步屏障,找到下一个异步消息
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
// 如果上面有同步屏障,但却没找到异步消息,
// 那么msg会循环到链表尾,也就是msg==null
if (msg != null) {
···
} else {
// 没有消息,进入阻塞状态
nextPollTimeoutMillis = -1;
}
···
}
}
}
使用异步类型的Handler发送的全部Message都是异步的 给Message标志异步
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
// 这里赋值
mAsynchronous = async;
}
long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
// 赋值
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
if (looper == null) throw new NullPointerException("looper must not be null");
return new Handler(looper, null, true);
}
public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
if (looper == null) throw new NullPointerException("looper must not be null");
if (callback == null) throw new NullPointerException("callback must not be null");
return new Handler(looper, callback, true);
}
if (async) {
flags |= FLAG_ASYNCHRONOUS;
} else {
flags &= ~FLAG_ASYNCHRONOUS;
}
}
我们的同步消息最多可能被延迟一帧的时间,也就是16ms,才会被执行 主线程Looper造成过大的压力,在VSYNC信号到来之时,才集中处理所有消息