Handler屏障消息和IdleHandler

本文详细解释了Android中的屏障消息如何提升异步消息的执行优先级,包括发送屏障消息、异步消息的发送与移除,以及IdleHandler在消息空闲时的处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.屏障消息

屏障消息也叫同步屏障消息,作用是提升异步消息的执行优先级的。
首先假设有这样一种场景,在主线程的MessageQuee里面存在很多个消息在排队等待处理,然后这个时候我们去给主线程发送了一条刷新UI的Message,那么这条消息就需要高优处理。
为了实现这一效果,我们需要做3件事情:

1.1.发送屏障消息

给对应的MessageQueue发送一条屏障消息,以ViewRootImpl的scheduleTraversals方法举例:

 //发送同步屏障消息
  mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();

这里的mTraversalBarrier是返回回来的一个token标志,在后续使用完屏障消息后,需要用这个token去移除屏障消息。

1.2. 发送一条异步消息

首先我们需要知道的是,我们正常往handler发送的消息都是同步消息,即Message中的变量isAsynchronous是false的,只有当isAsynchronous的值是 true,才表示是一个异步消息。
我们可以通过设置这个属性,来标记消息是否是异步消息:

Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
1.3. 移除屏障消息

使用完屏障消息后,需要手动移除,避免不能处理同步消息的情况发生:

//移除同步屏障消息
         mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
1.4.屏障消息的运行逻辑
Message next() {
   
   
    ......
    int nextPollTimeoutMillis = 0;
    for (;;) {
   
   
        ......
        
        // 阻塞,nextPollTimeoutMillis为等待时间,如果为-1则会一直阻塞
        nativePollOnce(ptr, nextPollTimeoutMillis);
        
        synchronized (this) {
   
   
            // Try to retrieve the next message.  Return if found.
            // 下面的代码目的是获取一个可用的消息,如果找到就return,
            // 没找到就继续后面我省略的代码(省略了IdHandler的相关代码)
            
            // 获取时间,还是通过uptimeMillis这个方法
            final long now = SystemClock.uptimeMillis();
            Message prevMsg = null;
            Message msg = mMessages;
            // 如果队列头部消息为屏障消息,即“target”为空的消息,则去寻找队列中的异步消息
            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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值