基础数据结构定义:
struct AMessage : public RefBase {
AMessage();
AMessage(uint32_t what, const sp
private:
friend struct ALooper; // deliver()
uint32_t mWhat;
// used only for debugging
ALooper::handler_id mTarget;
wp
wp
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
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
setObjectInternal(name, obj, kTypeObject);
}
void AMessage::setBuffer(const char *name, const sp
setObjectInternal(name, sp
}
void AMessage::setMessage(const char *name, const sp
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
const Item *item = findItem(name, kTypeBuffer);
if (item) {
*buf = (ABuffer *)(item->u.refValue);
return true;
}
return false;
}
bool AMessage::findMessage(const char *name, sp
const Item *item = findItem(name, kTypeMessage);
if (item) {
*obj = static_cast
return true;
}
return false;
}
消息发送
status_t AMessage::post(int64_t delayUs) {
sp
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
Mutex::Autolock autoLock(mLock);
int64_t whenUs;
if (delayUs > 0) {
whenUs = GetNowUs() + delayUs;
} else {
whenUs = GetNowUs();
}
List
while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {
++it;
}
在Alooper的mEventQueue消息队列中,是按timeUs进行排序的
1)一般使用方式
sp
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
token是消息发送方填入,response是接收方响应后填入
看到AMessage里面的token
status_t AReplyToken::setReply(const sp
if (mReplied) {
ALOGE("trying to post a duplicate reply");
return -EBUSY;
}
CHECK(mReply == NULL);
mReply = reply;
mReplied = true;
return OK;
}
bool retrieveReply(sp
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
// 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
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
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
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的子类对象来真正处理消息,没看到有消息积压这类告警和提示