OpenHarmony源码分析——EventHanler
1. EventHandler简介
EventHandler提供了鸿蒙系统线程见通信的基本能力,是一种处理线程之间通信的机制。熟悉Android开发的同学,类似于Android中的Handler机制。
EventHandler机制主要包括EventRunner、InnerEvent、EventHandler、EventQueue。可通过EventRunner创建新线程来执行耗时任务。
源码传送门
2. EventHandler核心类
类 | 功能介绍 |
---|---|
EventRunner | 消息队列的循环分发器,每个线程只有一个EventRunner,主要用于管理消息队列EventQueue,不断地从队列中取出InnerEvent分发至对应的EventHandler处理。 |
InnerEvent | 线程之间消息传递的实体封装,EventHandler接收与处理的消息对象。EventHandler待处理的InnerEvent的优先级可在IMMEDIATE、HIGH、LOW、IDLE中选择,并设置合适的delayTime。 |
EventHandler | 发送和处理消息的核心类,通过绑定一个EventRunner实现对消息队列进行循环分发的功能。 |
EventQueue | 线程消息队列,管理InnerEvent,在初始化EventRunner对象时需要创建一个与之关联的EventQueue。 |
3. 运行机制
熟悉Android handler机制的同学,会发现EventHandler运行机制与Android handler机制类似,EventRunner相当于Android中的looper,EventQueue相当于Android中的MessageQueue。
EventHandler实现线程间通信的主要流程如下所示:
- EventHandler通过sendEvent方法将InnerEvent事件投递到EventRunner所创建的EventQueue中;
- EventRunner循环从EventQueue中取出InnerEvent进行处理;
- 通过getOwner获取到handler,调用handler的DistributeEvent处理;
这几个类之间的对应关系如下所示:
4. 源码分析
4.1 源码目录
base/notification/eventhandler
├── interfaces
│ ├── inner_api # 内部接口存放目录
│ └── kits # 外部接口存放目录
│ └── native # C/C++接口
├── frameworks # 包管理服务框架代码
│ ├── eventhandler # 内部实现存放目录
│ ├── napi # js接口实现存放目录
│ └── native # C/C++接口实现存放目录
└── test # 测试目录
4.2 核心代码分析
核心类的类图如下所示:
首先分析EventHandler,类文件event_handler.cpp
在创建EventHandler实例时,会绑定一个EventRunner
EventHandler::EventHandler(const std::shared_ptr<EventRunner> &runner) : eventRunner_(runner)
{
HILOGD("enter");
}
EventRunner创建又是怎么实现的呢?EventRunner的create方法在创建Runner线程的同时会实例化一个EventQueue,并赋值给类内部的成员变量queue_ 。
std::shared_ptr<EventRunner> EventRunner::Create(bool inNewThread)
{
HILOGD("inNewThread is %{public}d", inNewThread);
if (inNewThread) {
HILOGI("EventRunner created");
return Create(std::string());
}
// Constructor of 'EventRunner' is private, could not use 'std::make_shared' to construct it.
std::shared_ptr<EventRunner> sp(new (std::nothrow) EventRunner(false));
if (sp == nullptr) {
HILOGI("Failed to create EventRunner Instance");
return nullptr;
}
auto innerRunner = std::make_shared<EventRunnerImpl>(sp);
sp->innerRunner_ = innerRunner;
sp->queue_ = innerRunner->GetEventQueue();
return sp;
}
EventRunner的Runner线程轮询queue_,取出队列中的InnerEvent事件,并处理该事件。
void Run(