0
点赞
收藏
分享

微信扫一扫

Android Handler 同步屏障


简单理解

异步消息相比同步消息要优先执行,好比 :

当一堆人在排队进周杰伦演唱会时候,周杰伦来了,就通知保安,周杰伦来了,于是优先给周杰伦进去,等周杰伦进去后,其他人再按顺序进去

专业解释就是:

当开启了同步障碍时,Looper在获取下一个要执行的消息时,会在链表中寻找第一个要执行的异步消息,如果没有找到异步消息,就让当前线程沉睡。

nativeWake()方法和nativePollOnce()方法采用了Linux的epoll机制,其中nativePollOnce()的第二个值,当它是-1时会一直沉睡,直到被主动唤醒为止,当它是0时不会沉睡,当它是大于0的值时会沉睡传入的值那么多的毫秒时间。epoll机制实质上是让CPU沉睡,来保障当前线程一直在运行而不中断或者卡死,这也是Looper#loop()死循环为什么不会导致住县城ANR的根本原因。

Android 中异步消息应用场景:

在ViewRootImpl.java中有使用它:

void scheduleTraversals() {
if (!mTraversalScheduled) {

mTraversalScheduled = true;
// 开启当前Handler的同步屏障
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 发送一条异步消息
mChoreographer.postCallback(..., mTraversalRunnable, null);

if (!mUnbufferedInputDispatch) {
cheduleConsumeBatchedInput();
}

notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}

这里的 ​​Handler​​​ 使用的是主线程的 ​​Looper​​​,因此这里会阻断主线程 ​​Looper​​​ 的其他同步消息,在​​ViewRootImpl​​​ 和 ​​Choreographer​​​ 中多次使用到了异步消息,以完成 ​​View​​ 的整个绘制流程。

当我们点击页面的某个控件时,希望瞬间得到它的回应,而不是卡在那里,最起码有个圈圈在转也行。当我们点击某个按钮,此时开启了一个 ​​Activity​​​,如果队列中此时有很多消息在排队等候呢?那么这个 ​​Activity​​ 的测量、布局和绘制就得一直等到所有消息被处理完成才能执行,此时我们会看到页面一直黑着或者一直白着,反正不是我们想要的效果,因此如果这个消息队列有一个优先级的特点,那么不久可以解决这个问题了吗

停止一个 HandlerThread

while (true) {
Message msg = queue.next(); // might block
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}

long wallStart = 0;
long threadStart = 0;

// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
wallStart = SystemClock.currentTimeMicro();
threadStart = SystemClock.currentThreadTimeMicro();
}

msg.target.dispatchMessage(msg);

​quit()​

public void quit() {
Message msg = Message.obtain();
// NOTE: By enqueueing directly into the message queue, the
// message is left with a null target. This is how we know it is
// a quit message.
mQueue.enqueueMessage(msg, 0);
}

mHandlerThread.getLooper().quit();

参考链接

  • ​​Android筑基——可视化方式理解 Handler 的同步屏障机制​​
  • ​​每日问答 Handler应该是大家再熟悉不过的类了,那么其中有个同步屏障机制,你了解多少呢?​​
  • ​​Android Handler 源码分析​​
  • ​​揭秘 Android 消息机制之同步屏障:target==null ?​​
  • ​​终止Android中HandlerThread的方法​​
  • ​​Android消息机制Message的target==null的黑科技​​


举报

相关推荐

0 条评论