用过android的同学,一定会对Handler很熟悉,使用起来也特别方便。自己看Handler的代码,你会发现其实就是一个简单的消息队列机制。Obotcha模仿android(也可以说是抄)构建了自己的一个Handler。
首先介绍Obotcha中关键的几个类,
Handler
handleMessage:这个虚函数是用来实现各种消息时间的处理。
getLooper:返回消息队列,这样其他Handler构造时如果传入这个消息队列,那该Handler的信息就会往这个消息队列发送
sendEmptyMessage:发送消息
DECLARE_CLASS(Handler) IMPLEMENTS(HandlerTarget){
...
virtual void handleMessage(sp<_Message>){};
...
Looper getLooper();
...
int sendEmptyMessage(int what);
...
}
我们看一下消息发送的实现:
int _Handler::sendMessageDelayed(sp<_Message> msg, long delay) {
msg->setTarget(AutoClone(this));
msg->nextTime = st(System)::currentTimeMillis() + delay;
return mLooper->getQueue()->enqueueMessage(msg);
}
没有什么特殊处理,就是往looper的queue里面插入msg。注意这一句:msg->setTarget(AutoClone(this));这个就是之后消息队列处理时候判断具体是往那个handler发送的。
Looper
looper里面最重要的就是维护了一个用来存放msg的消息队列。我们看一下looper中最重要的函数loop
void _Looper::loop() {
while(1) {
auto msg = mQueue->next();
if(msg != nullptr) {
auto target = msg->getTarget();
auto runnable = msg->getRunnable();
if(runnable != nullptr) {
runnable->run();
} else {
target->handleMessage(msg);
}
continue;
}
break;
}
}
实现就是一个循环不停的读取mQueue中的数据。如果这个msg的runnable非空的话,那就执行runnable,这种场景主要是对应lambda函数的,类似下面的代码:
handler->sendMessage([]{
xxxxxxx
});
剩余的就调用mTarger的handleMessage,这样就又回到了handler中的handleMessage实现(这个是用户可以自己定义的)。这种主要对应下面的场景:
handler->sendEmptyMessage(EVENT_INI);
HandlerThread
handlerThead本身就是一个thread,但是它的run函数运行了looper的loop
void _HandlerThread::run() {
mLooper->loop();
}
这样每次创建一个handlerThread就默认生成了一个新的消息队列。然后就能循环读取消息队列里面的数据了。
综上可以看出来,起始这3个类的思路基本就是抄袭了Android的Handler,略有简化。不过使用起来还是非常方便的。哈哈,大家有空可以看一下handler的详细代码:
Obotcha/util/handler at master · wangsun1983/Obotcha · GitHub