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