parent
589520575d
commit
23291525ce
@ -0,0 +1,81 @@ |
||||
--- |
||||
消息屏障 |
||||
--- |
||||
|
||||
```java |
||||
// 插入屏障 |
||||
private int postSyncBarrier(long when){ |
||||
synchronized(this){ |
||||
final int token = mNextBarrierToken++; |
||||
final Message msg = Message.obtain(); |
||||
msg.markInUse(); |
||||
msg.when = when; |
||||
msg.arg1 = token; |
||||
return token; |
||||
} |
||||
} |
||||
// 删除屏障 |
||||
public void removeSyncBarrier(int token){ |
||||
synchronized(this){ |
||||
if(needWake && !mQuitting){ |
||||
nativeWake(mPtr); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 处理屏障 |
||||
Message next(){ |
||||
for(;;){ |
||||
nativePollOnce(ptr, nextPollTimeoutMillis); |
||||
synchronized(this){ |
||||
// 如果第一条消息就是屏障,就往后遍历,看看有没有异步消息 |
||||
// 如果没有,就无限休眠,等待被别人唤醒 |
||||
// 如果有,就看离这个消息触发时间还有多久,设置一个超时,继续休眠 |
||||
continue; |
||||
} |
||||
} |
||||
} |
||||
boolean enqueueMessage(Message msg, long when){ |
||||
synchronized(this){ |
||||
// 给消息插到消息队列 |
||||
// 如果插到队列头了,如果当前线程是休眠的,就要唤醒他 |
||||
// 如果没插到队列头,如果当前线程是休眠的,并且队列头是屏障 |
||||
// 并且当前消息是最早的一条异步消息,就要唤醒线程 |
||||
if(needWake){ |
||||
nativeWake(mPtr); |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
``` |
||||
|
||||
#### 看几个问题? |
||||
|
||||
1. 消息队列为空的时候,插一个屏障,会触发 IdleHandler 嘛? |
||||
2. 如果删除了屏障,消息队列为空了,会触发 IdleHandler 嘛? |
||||
3. 如果消息队列只有一个屏障消息,插一个普通消息会 IdleHandler 嘛? |
||||
4. 如果消息队列只有一个屏障消息,插一个异步消息会 IdleHandler 嘛? |
||||
|
||||
Framework 里面哪里用到了消息屏障? |
||||
|
||||
```java |
||||
void scheduleTraversals(){ |
||||
if(!mTraversalScheduled){ |
||||
mTraversalScheduled = true; |
||||
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); |
||||
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); |
||||
} |
||||
} |
||||
void doTraversal(){ |
||||
if(mTraversalScheduled){ |
||||
mTraversalScheduled = false; |
||||
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier); |
||||
performTraversals(); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
#### 总结 |
||||
|
||||
1. 消息屏障 |
||||
2. 异步消息 |
Loading…
Reference in new issue