基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)定義:
struct AMessage : public RefBase {
? ? AMessage();
? ? AMessage(uint32_t what, const sp<const AHandler> &handler);
private:
? ? friend struct ALooper; // deliver()
? ? uint32_t mWhat;??
? ? // used only for debugging
? ? ALooper::handler_id mTarget;
? ? wp<AHandler> mHandler;
? ? wp<ALooper> mLooper;
struct Item {
? ? ? ? union {
? ? ? ? ? ? int32_t int32Value;
? ? ? ? ? ? int64_t int64Value;
? ? ? ? ? ? size_t sizeValue;
? ? ? ? ? ? float floatValue;
? ? ? ? ? ? double doubleValue;
? ? ? ? ? ? void *ptrValue;
? ? ? ? ? ? RefBase *refValue;
? ? ? ? ? ? AString *stringValue;
? ? ? ? ? ? Rect rectValue;
? ? ? ? } u;
? ? ? ? const char *mName;
? ? ? ? size_t? ? ? mNameLength;
? ? ? ? Type mType;
? ? ? ? void setName(const char *name, size_t len);
? ? };
? ? enum {
? ? ? ? kMaxNumItems = 64
? ? };
? ? Item mItems[kMaxNumItems];? //amessage里面最多可以放64個(gè)數(shù)據(jù)
? ? size_t mNumItems;
具體實(shí)現(xiàn)
void AMessage::Item::setName(const char *name, size_t len) {
? ? mNameLength = len;
? ? mName = new char[len + 1];
? ? memcpy((void*)mName, name, len + 1);
}
取數(shù)據(jù),
const AMessage::Item *AMessage::findItem(
? ? ? ? const char *name, Type type) const {
? ? size_t i = findItemIndex(name, strlen(name));
? ? if (i < mNumItems) {
? ? ? ? const Item *item = &mItems[i];
? ? ? ? return item->mType == type ? item : NULL;
? ? }
? ? return NULL;
}
要是u里面直觀類型
bool AMessage::findAsFloat(const char *name, float *value) const {
? ? size_t i = findItemIndex(name, strlen(name));
? ? if (i < mNumItems) {
? ? ? ? const Item *item = &mItems[i];
? ? ? ? switch (item->mType) {
? ? ? ? ? ? case kTypeFloat:
? ? ? ? ? ? ? ? *value = item->u.floatValue;
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? case kTypeDouble:
? ? ? ? ? ? ? ? *value = (float)item->u.doubleValue;
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? case kTypeInt64:
? ? ? ? ? ? ? ? *value = (float)item->u.int64Value;
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? case kTypeInt32:
? ? ? ? ? ? ? ? *value = (float)item->u.int32Value;
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? case kTypeSize:
? ? ? ? ? ? ? ? *value = (float)item->u.sizeValue;
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? return false;
? ? ? ? }
? ? }
? ? return false;
}
存string,string內(nèi)容是拷貝過(guò)去的
void AMessage::setString(
? ? ? ? const char *name, const char *s, ssize_t len) {
? ? Item *item = allocateItem(name);
? ? item->mType = kTypeString;
? ? item->u.stringValue = new AString(s, len < 0 ? strlen(s) : len);
}
amessage,abuffer,object這些是存指針
void AMessage::setObjectInternal(
? ? ? ? const char *name, const sp<RefBase> &obj, Type type) {
? ? Item *item = allocateItem(name);
? ? item->mType = type;
? ? if (obj != NULL) { obj->incStrong(this); }
? ? item->u.refValue = obj.get();
}
void AMessage::setObject(const char *name, const sp<RefBase> &obj) {
? ? setObjectInternal(name, obj, kTypeObject);
}
void AMessage::setBuffer(const char *name, const sp<ABuffer> &buffer) {
? ? setObjectInternal(name, sp<RefBase>(buffer), kTypeBuffer);
}
void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
? ? Item *item = allocateItem(name);
? ? item->mType = kTypeMessage;
? ? if (obj != NULL) { obj->incStrong(this); }
? ? item->u.refValue = obj.get();
}
取buffer等對(duì)象,是直接取到原先的強(qiáng)指針
bool AMessage::findBuffer(const char *name, sp<ABuffer> *buf) const {
? ? const Item *item = findItem(name, kTypeBuffer);
? ? if (item) {
? ? ? ? *buf = (ABuffer *)(item->u.refValue);
? ? ? ? return true;
? ? }
? ? return false;
}
bool AMessage::findMessage(const char *name, sp<AMessage> *obj) const {
? ? const Item *item = findItem(name, kTypeMessage);
? ? if (item) {
? ? ? ? *obj = static_cast<AMessage *>(item->u.refValue);
? ? ? ? return true;
? ? }
? ? return false;
}
消息發(fā)送
status_t AMessage::post(int64_t delayUs) {
? ? sp<ALooper> looper = mLooper.promote();
? ? if (looper == NULL) {
? ? ? ? ALOGW("failed to post message as target looper for handler %d is gone.", mTarget);
? ? ? ? return -ENOENT;
? ? }
? ? looper->post(this, delayUs);
? ? return OK;
}
void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
? ? Mutex::Autolock autoLock(mLock);
? ? int64_t whenUs;
? ? if (delayUs > 0) {
? ? ? ? whenUs = GetNowUs() + delayUs;
? ? } else {
? ? ? ? whenUs = GetNowUs();
? ? }
? ? List<Event>::iterator it = mEventQueue.begin();
? ? while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {
? ? ? ? ++it;
? ? }
在Alooper的mEventQueue消息隊(duì)列中,是按timeUs進(jìn)行排序的
1)一般使用方式
sp<AMessage> notify = mNotify->dup();
? ? ? ? notify->setInt32("what", kWhatInformSender);
? ? ? ? notify->setInt64("avgLatencyUs", avgLatencyUs);
? ? ? ? notify->setInt64("maxLatencyUs", maxLatencyUs);
? ? ? ? notify->post();
接收方
case kWhatInformSender:
? ? ? ? {
? ? ? ? ? ? int64_t avgLatencyUs;
? ? ? ? ? ? CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs));
? ? ? ? ? ? int64_t maxLatencyUs;
? ? ? ? ? ? CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs));
2) 需要響應(yīng),:awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response)
token是消息發(fā)送方填入,response是接收方響應(yīng)后填入
看到AMessage里面的token
status_t AReplyToken::setReply(const sp<AMessage> &reply) {
? ? if (mReplied) {
? ? ? ? ALOGE("trying to post a duplicate reply");
? ? ? ? return -EBUSY;
? ? }
? ? CHECK(mReply == NULL);
? ? mReply = reply;
? ? mReplied = true;
? ? return OK;
}
bool retrieveReply(sp<AMessage> *reply) {
? ? ? ? if (mReplied) {
? ? ? ? ? ? *reply = mReply;
? ? ? ? ? ? mReply.clear();
? ? ? ? }
? ? ? ? return mReplied;
? ? }
要結(jié)合ALooper里面看,在ALooper里面對(duì)replytoken進(jìn)行設(shè)置,消息回復(fù)時(shí)postReply設(shè)置reply,條件condition通知awaitResponse觸發(fā)收到reply
// to be called by AMessage::postAndAwaitResponse only
status_t ALooper::awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response) {
? ? // return status in case we want to handle an interrupted wait
? ? Mutex::Autolock autoLock(mRepliesLock);
? ? CHECK(replyToken != NULL);
? ? while (!replyToken->retrieveReply(response)) {
? ? ? ? {
? ? ? ? ? ? Mutex::Autolock autoLock(mLock);
? ? ? ? ? ? if (mThread == NULL) {
? ? ? ? ? ? ? ? return -ENOENT;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? mRepliesCondition.wait(mRepliesLock);
? ? }
? ? return OK;
}
status_t ALooper::postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &reply) {
? ? Mutex::Autolock autoLock(mRepliesLock);
? ? status_t err = replyToken->setReply(reply);
? ? if (err == OK) {
? ? ? ? mRepliesCondition.broadcast();
? ? }
? ? return err;
}
====================================
struct ALooper::LooperThread : public Thread {
? ? LooperThread(ALooper *looper, bool canCallJava)
? ? ? ? : Thread(canCallJava),
? ? ? ? ? mLooper(looper),
? ? ? ? ? mThreadId(NULL) {
? ? }
ALooper是起線程
ALooper::loop() {? //不停循環(huán) 發(fā)送消息
mEventQueue.erase(mEventQueue.begin());
event.mMessage->deliver();
//post是將消息放到發(fā)送隊(duì)列里面,如果當(dāng)前隊(duì)列為空,則會(huì)signal喚醒loop()函數(shù)中等待,linux的邊緣觸發(fā)
void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
? ? if (it == mEventQueue.begin()) {
? ? ? ? mQueueChangedCondition.signal();
? ? }
? ? mEventQueue.insert(it, event);
消息如何響應(yīng)處理
、、、
bool ALooper::loop() {
? ? Event event;
? ? {
? ? ? ? Mutex::Autolock autoLock(mLock);
? ? ? ? if (mThread == NULL && !mRunningLocally) {
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? if (mEventQueue.empty()) {
? ? ? ? ? ? //當(dāng)前沒(méi)有消息處理,等待喚醒,喚醒后直接return
? ? ? ? ? ? mQueueChangedCondition.wait(mLock);
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? int64_t whenUs = (*mEventQueue.begin()).mWhenUs;
? ? ? ? int64_t nowUs = GetNowUs();
? ? ? ? if (whenUs > nowUs) {
? ? ? ? ? ? int64_t delayUs = whenUs - nowUs;
? ? ? ? ? ? mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? event = *mEventQueue.begin();
? ? ? ? mEventQueue.erase(mEventQueue.begin());
? ? }
? //deliver才是讓AMessage對(duì)應(yīng)的Hander來(lái)進(jìn)行處理
? ? event.mMessage->deliver();
? ? // NOTE: It's important to note that at this point our "ALooper" object
? ? // may no longer exist (its final reference may have gone away while
? ? // delivering the message). We have made sure, however, that loop()
? ? // won't be called again.
? ? return true;
}
void AMessage::deliver() {
? ? sp<AHandler> handler = mHandler.promote();
? ? if (handler == NULL) {
? ? ? ? ALOGW("failed to deliver message as target handler %d is gone.", mTarget);
? ? ? ? return;
? ? }
? ? handler->deliverMessage(this);
}
、、、
總結(jié)下android的消息機(jī)制,就是amessage->post加入到ALooper的mEventQueue List 隊(duì)列,然后?
ALooper線程不停looper來(lái)進(jìn)行處理,從mEventQueue List取出一個(gè)個(gè)AMessage,根據(jù)保存的Handler對(duì)象,調(diào)用Handler的子類對(duì)象來(lái)真正處理消息,沒(méi)看到有消息積壓這類告警和提示