1.安卓N版本ALooperRoster.h原文
#ifndef A_LOOPER_ROSTER_H_
#define A_LOOPER_ROSTER_H_
#include <media/stagefright/foundation/ALooper.h>
#include <utils/KeyedVector.h>
#include <utils/String16.h>
namespace android {
struct ALooperRoster {
ALooperRoster();
ALooper::handler_id registerHandler(
const sp<ALooper> looper, const sp<AHandler> &handler);
void unregisterHandler(ALooper::handler_id handlerID);
void unregisterStaleHandlers();
void dump(int fd, const Vector<String16>& args);
private:
struct HandlerInfo {
wp<ALooper> mLooper;
wp<AHandler> mHandler;
};
Mutex mLock;
KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
ALooper::handler_id mNextHandlerID;
DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
};
} // namespace android
#endif // A_LOOPER_ROSTER_H_
1.1条件编译
#ifndef A_LOOPER_ROSTER_H_
#define A_LOOPER_ROSTER_H_
...
...
...
#endif // A_LOOPER_ROSTER_H_
条件编译宏,防止该头文件被重复包含而导致的重复定义。
1.2包含的头文件
#include <media/stagefright/foundation/ALooper.h>
#include <utils/KeyedVector.h>
#include <utils/String16.h>
包含了定义ALooperRoster.h所需要引用的文件。
1.3名字空间
namespace android {
...
...
...
}
2.成员变量
private:
struct HandlerInfo {
wp<ALooper> mLooper;
wp<AHandler> mHandler;
};
Mutex mLock;
KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
ALooper::handler_id mNextHandlerID;
2.1struct HandlerInfo
struct HandlerInfo {
wp<ALooper> mLooper;
wp<AHandler> mHandler;
};
该结构提有有两个域,这两个域就是绑定在一起的一对儿ALooper和AHandler,KeyedVector<ALooper::handler_id, HandlerInfo>是用来存放很多这样的ALooper,AHandler对儿。每一对儿有唯一的键值:ALooper::handler_id。
注意:该键值是唯一的,由ALooper::handler_id mNextHandlerID来计数,从1开始计数,每有一对儿这样的ALooper,AHandler对儿进行注册,则该值就自增1。
3.ALooperRoster的实现
3.1构造函数的实现
下面贴出安卓N版本下ALooperRoster的构造函数
ALooperRoster::ALooperRoster()
: mNextHandlerID(1) {
}
很简单,就是将mNextHandlerID计数器的值置为1,表示从1开始计数,每有一对儿ALooper,AHandler进行注册,当前该值作为该ALooper,AHandler对儿的键值标识,然后将该值自增1.
3.2registerHandler函数的实现
下面贴出安卓N版本下registerHandler函数的实现
ALooper::handler_id ALooperRoster::registerHandler(
const sp<ALooper> looper, const sp<AHandler> &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, looper);
return handlerID;
}
可以看出传进来的参数哦是一对儿ALooper,AHandler的引用,并且AHandler的id()返回值必须要为0,这是因为定义0表示未注册,当完成注册后将mNextHandlerID的值赋给AHandler的mID.
从下面两行代码可以看出。
ALooper::handler_id handlerID = mNextHandlerID++;
handler->setID(handlerID, looper);
这个时候AHandler的mID就不为0了,表示已经注册过。
3.3unregisterHandler函数的实现
下面贴出安卓N版本下unregisterHandler函数的实现
void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
Mutex::Autolock autoLock(mLock);
ssize_t index = mHandlers.indexOfKey(handlerID);
if (index < 0) {
return;
}
const HandlerInfo &info = mHandlers.valueAt(index);
sp<AHandler> handler = info.mHandler.promote();
if (handler != NULL) {
handler->setID(0, NULL);
}
mHandlers.removeItemsAt(index);
}
可以看到传入的参数是表示一对儿ALooper,AHandler的键值,该键值保存在注册成功后的AHandler的mID中。
ssize_t index = mHandlers.indexOfKey(handlerID);
即使用键值来找到对应的ALooper,AHandler存放的索引。
const HandlerInfo &info = mHandlers.valueAt(index);即通过索引找到该ALooper,AHandler的引用,也即HandlerInfo结构体的引用。
if (handler != NULL) {
handler->setID(0, NULL);
}
如果handler不为空则调用handler->setID将其mID置为0,表示未经注册过。
mHandlers.removeItemsAt(index);
通过索引来移除当前这对儿ALooper,AHandler。