可以插入多个
同步屏障(Sync Barrier)可以插入多个,它们会以时间顺序存储在 MessageQueue 中,每个屏障会占据一个位置,并记录其 token(标识符)。但它们的行为机制要注意以下几点:
多个同步屏障的行为机制
1. 插入多个屏障是允许的
每次调用:
int token = MessageQueue.postSyncBarrier();
系统都会创建一个新的 Message,它的 target == null,并插入到 MessageQueue 中,同时返回一个唯一 token,用于后续移除。
2. 同步屏障是按插入顺序生效的
当 nativePollOnce 或 MessageQueue.next() 遍历消息队列时:
• 如果遇到同步屏障(即 target == null),则会跳过所有后续的同步消息,直到遇到一个异步消息。
• 如果插入了多个屏障,那么:
• 只要第一个屏障没有移除,后续屏障前的同步消息都不会被处理。
• 不会同时处理多个屏障,因为只要第一个屏障在,后续同步消息都被阻塞。
3. 移除需要手动调用
每个屏障都有对应的 token,你需要用:
MessageQueue.removeSyncBarrier(token);
才能移除。
示例情景:多个屏障的插入与影响
假设 MessageQueue 中有如下内容(从前往后):
普通同步消息 A
—— 屏障1
普通同步消息 B
异步消息 C
—— 屏障2
普通同步消息 D
执行 next() 时的行为:
• 首先遇到屏障1 → 跳过 A、B(因为它们是同步消息)
• 继续查找异步消息,发现 C → 执行 C
• 即使存在屏障2,当前行为也受屏障1控制,除非屏障1被移除。
注意点
• 同步屏障不是无限制使用的工具,滥用会导致同步消息“永远执行不到”,从而引发主线程卡死或功能失效。
• 典型错误是插入后忘记 remove,比如 Choreographer 插入后异常终止导致 UI 不再刷新。