AMessage

基础数据结构定义:

struct AMessage : public RefBase {

    AMessage();

    AMessage(uint32_t what, const sp &handler);

private:

    friend struct ALooper; // deliver()

    uint32_t mWhat;  

    // used only for debugging

    ALooper::handler_id mTarget;

    wp mHandler;

    wp 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个数据

    size_t mNumItems;


具体实现

void AMessage::Item::setName(const char *name, size_t len) {

    mNameLength = len;

    mName = new char[len + 1];

    memcpy((void*)mName, name, len + 1);

}

取数据,

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内容是拷贝过去的

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 &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 &obj) {

    setObjectInternal(name, obj, kTypeObject);

}

void AMessage::setBuffer(const char *name, const sp &buffer) {

    setObjectInternal(name, sp(buffer), kTypeBuffer);

}

void AMessage::setMessage(const char *name, const sp &obj) {

    Item *item = allocateItem(name);

    item->mType = kTypeMessage;

    if (obj != NULL) { obj->incStrong(this); }

    item->u.refValue = obj.get();

}

取buffer等对象,是直接取到原先的强指针

bool AMessage::findBuffer(const char *name, sp *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 *obj) const {

    const Item *item = findItem(name, kTypeMessage);

    if (item) {

        *obj = static_cast(item->u.refValue);

        return true;

    }

    return false;

}


消息发送

status_t AMessage::post(int64_t delayUs) {

    sp 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 &msg, int64_t delayUs) {

    Mutex::Autolock autoLock(mLock);

    int64_t whenUs;

    if (delayUs > 0) {

        whenUs = GetNowUs() + delayUs;

    } else {

        whenUs = GetNowUs();

    }

    List::iterator it = mEventQueue.begin();

    while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {

        ++it;

    }

在Alooper的mEventQueue消息队列中,是按timeUs进行排序的

1)一般使用方式

sp 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) 需要响应,:awaitResponse(const sp &replyToken, sp *response)

token是消息发送方填入,response是接收方响应后填入


看到AMessage里面的token

status_t AReplyToken::setReply(const sp &reply) {

    if (mReplied) {

        ALOGE("trying to post a duplicate reply");

        return -EBUSY;

    }

    CHECK(mReply == NULL);

    mReply = reply;

    mReplied = true;

    return OK;

}

bool retrieveReply(sp *reply) {

        if (mReplied) {

            *reply = mReply;

            mReply.clear();

        }

        return mReplied;

    }

要结合ALooper里面看,在ALooper里面对replytoken进行设置,消息回复时postReply设置reply,条件condition通知awaitResponse触发收到reply

// to be called by AMessage::postAndAwaitResponse only

status_t ALooper::awaitResponse(const sp &replyToken, sp *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 &replyToken, const sp &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() {  //不停循环 发送消息

mEventQueue.erase(mEventQueue.begin());

event.mMessage->deliver();


//post是将消息放到发送队列里面,如果当前队列为空,则会signal唤醒loop()函数中等待,linux的边缘触发

void ALooper::post(const sp &msg, int64_t delayUs) {

    if (it == mEventQueue.begin()) {

        mQueueChangedCondition.signal();

    }

    mEventQueue.insert(it, event);


消息如何响应处理

、、、

bool ALooper::loop() {

    Event event;

    {

        Mutex::Autolock autoLock(mLock);

        if (mThread == NULL && !mRunningLocally) {

            return false;

        }

        if (mEventQueue.empty()) {

            //当前没有消息处理,等待唤醒,唤醒后直接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对应的Hander来进行处理

    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 handler = mHandler.promote();

    if (handler == NULL) {

        ALOGW("failed to deliver message as target handler %d is gone.", mTarget);

        return;

    }

    handler->deliverMessage(this);

}

、、、

总结下android的消息机制,就是amessage->post加入到ALooper的mEventQueue List 队列,然后 

ALooper线程不停looper来进行处理,从mEventQueue List取出一个个AMessage,根据保存的Handler对象,调用Handler的子类对象来真正处理消息,没看到有消息积压这类告警和提示

你可能感兴趣的:(AMessage)