postAndAwaitResponse()是AMessage的一个成员函数,从函数名称可以看出,调用postAndAwaitResponse(),不仅仅post消息,而且还需要等待Response。AMessage的postAndAwaitResponse()的功能实际上是通过ALooperRoster的postAndAwaitResponse()来实现的。
status_t AMessage::postAndAwaitResponse(sp<AMessage> *response) {
return gLooperRoster.postAndAwaitResponse(this, response);
}
ALooperRoster的postAndAwaitResponse()的实现如下所示:
status_t ALooperRoster::postAndAwaitResponse(
const sp<AMessage> &msg, sp<AMessage> *response) {
Mutex::Autolock autoLock(mLock);
uint32_t replyID = mNextReplyID++;
msg->setInt32("replyID", replyID);
status_t err = postMessage_l(msg, 0 /* delayUs */);
if (err != OK) {
response->clear();
return err;
}
ssize_t index;
while ((index = mReplies.indexOfKey(replyID)) < 0) {
mRepliesCondition.wait(mLock);
}
*response = mReplies.valueAt(index);
mReplies.removeItemsAt(index);
return OK;
}
首先是设置了replyID,后面的post reply和wait reply都是通过这个ID来匹配的。
然后通过调用postMessage_l()将消息放到消息队列。
最后就是在mReplies中检查replyID、等待并获得Response。
如果mReplies.indexOfKey(replyID)的结果小于0,说明消息还没有处理完毕,就需要等待mRepliesCondition.wait(mLock)。
在等什么呢?这里就需要看ALooperRoster的postReply(),postReply()的实现如下所示:
void ALooperRoster::postReply(uint32_t replyID, const sp<AMessage> &reply) {
Mutex::Autolock autoLock(mLock);
CHECK(mReplies.indexOfKey(replyID) < 0);
mReplies.add(replyID, reply);
mRepliesCondition.broadcast();
}
首先将replyID放到mReplies中,然后发送消息。
postAndAwaitResponse()等待到信号之后,再次检查replyID,然后获得期待已久的Response。
从上面的分析可以看出,postAndAwaitResponse()和postReply()必须出成对出现的。其实这就是一个线程间异步通信的过程。
这里还需要说明的一个函数是AMessage的senderAwaitsResponse(),功能实现过程如下所示:
bool AMessage::senderAwaitsResponse(uint32_t *replyID) const {
int32_t tmp;
bool found = findInt32("replyID", &tmp);
if (!found) {
return false;
}
*replyID = static_cast<uint32_t>(tmp);
return true;
}
这个函数的功能其实就是为postReply()找到所需要的replyID。因此,在调用postReply之前必须调用这个函数。