AMessage

基礎(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)看到有消息積壓這類告警和提示

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 3,127評(píng)論 0 3
  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,235評(píng)論 0 38
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,132評(píng)論 0 2
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,030評(píng)論 0 9
  • 作為AMessage/ALooper/AHandler中最復(fù)雜的一環(huán), AMessage被我放到了最后來(lái)講. 希望...
    TankWitch閱讀 4,237評(píng)論 0 1

友情鏈接更多精彩內(nèi)容