谷歌在Android native层实现的一个异步消息机制,在这个机制中几乎不存在同步锁,所有的处理都是异步的,将变量封装到一个消息AMessage结构体中,然后放到队列中去,后台专门有一个线程会从这个队列中取出消息然后执行,执行函数就是onMessageReceived
AMessage类
struct AMessage : public RefBase {
//构造函数,包括两个参数,第一个参数指明这是个什么消息,用于在onMessageReceived处理分支中进行匹配,第二个参数target用于后台线程在处理这个消息的时候知道发给哪个类处理
AMessage(uint32_t what = 0, ALooper::handler_id target = 0);
void setWhat(uint32_t what);
uint32_t what() const;
void setTarget(ALooper::handler_id target);
ALooper::handler_id target() const;
void clear();
//这个消息类中定义了一堆set和find方法,用于在在传递消息过程中携带各种信息
void setObject(const char *name, const sp &obj);
void setBuffer(const char *name, const sp &buffer);
void setMessage(const char *name, const sp &obj);
bool findBuffer(const char *name, sp *buffer) const;
bool findMessage(const char *name, sp *obj) const;
void post(int64_t delayUs = 0);
protected:
virtual ~AMessage(); 析构函数
private:
uint32_t mWhat;
ALooper::handler_id mTarget;
两个重要的私有成员变量
};
使用方法
正如开头部分看的那样,构造一个消息的过程如下:
void NuPlayer::start() {
(new AMessage(kWhatStart, id()))->post();
}
void AMessage::post(int64_t delayUs) {
gLooperRoster.postMessage(this, delayUs);
}
AHandler类分析----消息处理类的父类
struct AHandler : public RefBase {
AHandler()
: mID(0) { // mID的初始值为0
}
ALooper::handler_id id() const {
return mID; //id()这个函数用于返回内部变量mID的值,其初始值为0,但是会通过setID函数设置
}
sp<ALooper> looper();
protected:
virtual void onMessageReceived(const sp &msg) = 0;
private:
friend struct ALooperRoster;
ALooper::handler_id mID;
//下面这个函数正式在其友元类ALooperRoster的registerHandler中调用的
void setID(ALooper::handler_id id) {
mID = id;
}
};
ALooper::handler_id ALooperRoster::registerHandler(
const sp looper, const sp &handler) {
Mutex::Autolock autoLock(mLock);
if (handler->id() != 0) {
CHECK(!"A handler must only be registered once.");
return INVALID_OPERATION;
}
HandlerInfo info;
info.mLooper = looper;
info.mHandler = handler;
ALooper::handler_id handlerID = mNextHandlerID++;
mHandlers.add(handlerID, info);
handler->setID(handlerID);
//针对每个handler调用registerHandler的时候都会设置一个独一无二的handler_id,最后发送消息进行处理的时候就是通过这个独一无二的handler_id这个变量找到处理handler类的。
return handlerID;
}
在这个函数中针对这个looper和handler会构造一个HandlerInfo结构体,然后放到pair容器中。一个looper可以有多个handler,但是一一个handler只能跟一个looper。
ALooper类
struct ALooper : public RefBase {
typedef int32_t event_id;
typedef int32_t handler_id;
ALooper();
// Takes effect in a subsequent call to start().
void setName(const char *name);
handler_id registerHandler(const sp &handler);
void unregisterHandler(handler_id handlerID);
status_t start(
bool runOnCallingThread = false,
bool canCallJava = false,
int32_t priority = PRIORITY_DEFAULT
);
private:
friend struct ALooperRoster;
struct Event {
int64_t mWhenUs;
sp mMessage;
};
//后台存放事件的链表
List<Event> mEventQueue;
struct LooperThread;
//后台处理线程
sp<LooperThread> mThread;
void post(const sp &msg, int64_t delayUs);
bool loop();
};
ALooper 里面用Condition 做消息通知, List<Event>存储消息
能作为handler进行注册的类都必须是继承自AHandler这个类,注册的过程也是交给
gLooperRoster处理。
AMessage类:
消息类,用于构造消息,并通过post方法投递出去由ALooperRoster 类中转给ALooper
ALooperRoster类:中转类
将消息中转给ALooper 或者 AHandleReflector
ALooper
负责存储和转发AHandle的消息
LooperThread:
此线程循环调用ALooper的loop方法来转发消息
AHandleReflector类
消息处理类
使用方法
1.开始会创建一个ALooper对象, mLooper->start(...)
2.然后会实现一个AHandler的子类,
mLooper->registerhandler(objectXX)
子类实现一个onMessageReceived(XXXX),做收到消息的处理。
3.最后创建消息进行投递进入Message Queue。
创建AMessage里面,需要指定handleid,才能知道目标是发给谁。
mLooper(new ALooper)
mLooper->setName(name);
mLooper->start(
false, // runOnCallingThread
false, // canCallJava
ANDROID_PRIORITY_FOREGROUND);
mPlayer = new NUPlayer;
mLooper->registerHandler(mPlayer);
//mPlayer是一个AHandler
mReflector =new AhandlerReflector<RTSPSource.(this);
mLooper->registerHandler(mReflector);
(new AMessage(kWhatStart,id()))->post()