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之前必须调用这个函数。