消息机制之同步屏障
阻碍同步消息,优先处理异步消息
MessageQueue.postSyncBarrier()开启同步屏障
private int postSyncBarrier(long when) {
// Enqueue a new sync barrier token.
// We don't need to wake the queue because the purpose of a barrier is to stall it.
synchronized (this) {
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.markInUse();
msg.when = when;
msg.arg1 = token;
//没有设置target,即msg.target=null
Message prev = null;
Message p = mMessages;
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
if (prev != null) { // invariant: p == prev.next
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;
}
}
MessageQueue.next()
- msg.target=null,取异步消息
- msg.target!=null,取同步消息
Message next() {
//其他代码省略
int pendingIdleHandlerCount = -1; // -1 only during first iteration
// 1.如果nextPollTimeoutMillis=-1,一直阻塞不会超时。
// 2.如果nextPollTimeoutMillis=0,不会阻塞,立即返回。
// 3.如果nextPollTimeoutMillis>0,最长阻塞nextPollTimeoutMillis毫秒(超时)
// 如果期间有程序唤醒会立即返回。
int nextPollTimeoutMillis = 0;
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
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());
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
}
}
//其他代码省略..
}
MessageQueue.removeSyncBarrier()
移除同步屏障后,同步消息才会被处理
Message.setAsynchronous()
设置消息是否异步
HandlerThread
Thread的子类,方便初始化,方便获取Looper,保证线程安全。即子线程中创建Handler
HandlerThread.run()
初始化Looper,调用了notifyAll(),唤醒等待
HandlerThread.getLooper()
调用了wait(),等待并释放锁。等待run()初始化looper,防止返回null
IntentService
- HandlerThread的应用
- onCreate()创建HandlerThread
- onStart()发送消息给Handler
- onStartCommand()调用onStart()
- Handler.handleMessage()调用onHandleIntent用来执行耗时操作,调用stopSelf(id)停止服务(等所有消息处理完毕后才会停止,stopSelf()立即停止服务),回调onDestory()
- onDestory()调用Looper.quit()跳出消息循环