请谈谈什么是同步屏障?

更多面试题请看这里:https://interview.raoyunsoft.com/

面试题专栏会持续更新欢迎关注订阅

同步屏障是Android消息机制中的一种特殊控制手段,用于临时阻塞同步消息 ,优先处理异步高优先级消息(如UI绘制)。它的核心作用是确保关键任务不被普通消息延迟执行。


一、工作原理

  1. 设置屏障

    调用 handler.getLooper().getQueue().postSyncBarrier() 插入一个 target 为 null 的特殊消息(屏障消息):

    java 复制代码
    // 伪代码实现
    Message barrier = Message.obtain();
    barrier.when = SystemClock.uptimeMillis();
    mQueue.enqueueMessage(barrier); // 屏障入队
  2. 消息处理优先级

    Looper.loop() 执行 queue.next() 时:

    • 遇到屏障消息(target=null)时,跳过所有同步消息
    • 只处理标记为异步的消息(通过 msg.setAsynchronous(true)
  3. 屏障移除

    任务完成后需手动移除屏障:

    java 复制代码
    mQueue.removeSyncBarrier(token); // token是添加屏障时的返回值

二、关键特性

特性 同步消息 异步消息
标记方式 默认状态 msg.setAsynchronous(true)
屏障下的处理 被阻塞 优先执行
典型应用场景 普通业务逻辑 UI绘制、VSync信号响应

三、核心应用场景

View绘制流程 中保证优先级:

java 复制代码
// ViewRootImpl.java
void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        // 1. 插入同步屏障
        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
        // 2. 发送异步绘制消息
        mChoreographer.postCallback(
            Choreographer.CALLBACK_TRAVERSAL, 
            mTraversalRunnable, 
            null
        );
    }
}

设计意图:避免用户输入事件(同步消息)阻塞16ms内的UI渲染(异步消息),防止掉帧。


四、底层机制解析

  1. 消息队列结构

    屏障消息如同"闸门",后续同步消息被拦截

  2. next() 关键逻辑

    java 复制代码
    Message next() {
        for (;;) {
            if (msg != null && msg.target == null) {
                // 发现屏障,寻找异步消息
                do {
                    prevMsg = msg;
                    msg = msg.next;
                } while (msg != null && !msg.isAsynchronous());
            }
            return msg; // 只返回异步消息
        }
    }

五、开发者注意事项

  1. 慎用场景

    仅限系统级高优先级任务(如渲染、动画),滥用会导致普通消息饥饿

  2. 屏障必须移除

    未移除的屏障会造成同步消息永久阻塞:

    java 复制代码
    // 在Traversals执行后移除
    void unscheduleTraversals() {
        mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
    }
  3. 替代方案

    现代开发推荐使用 Choreographer + Vsync 机制管理绘制时序,而非直接操作屏障。

相关推荐
心念枕惊31 分钟前
PHP 在领域驱动(DDD)设计中的核心实践
android·开发语言·php
蜡台39 分钟前
Android WebView 设计指南
android·java·kotlin
晓梦林1 小时前
[Dest0g3 520迎新赛]EasyPHP-学习笔记
android·笔记·学习
Revolution611 小时前
数组本身没有 map,为什么还能直接调用:原型链怎样查找属性
前端·javascript·面试
未秃头的程序猿1 小时前
JDK 26的Value Class,我做了个性能测试,结果出乎意料
java·后端·面试
朱涛的自习室1 小时前
Munk AI 桌面端「预告」
android·前端·人工智能
程序员正茂2 小时前
Android studio中使用OpenCV C++库
android·c++·opencv·mobile
沉默王二2 小时前
携程员工:在携程4年,月薪3万左右,基本没涨薪了。不过挺满足的,毕竟稳定,福利也不错(附Agent面试题)
面试·openai·agent
Moment2 小时前
2026 了,前端转 AI 全栈我是这么学的 😍😍😍
前端·后端·面试
恋猫de小郭2 小时前
Android R8 为什么可以让 Kotlin 协程提速 2 倍?
android·前端·flutter