
OpenHarmony——EventHandler源码解析 原创 精华
作者:成飞
EventHandler是用于处理线程间通信的一种机制,可以通过EventRunner创建新线程,将耗时的操作放到新线程上执行。这样既不阻塞原来的线程,任务又可以得到合理的处理。比如:主线程使用EventHandler创建子线程,子线程做耗时的下载图片操作,下载完成后,子线程通过EventHandler通知主线程,主线程再更新UI。
基本概念
EventRunner是一种事件循环器,循环处理从该EventRunner创建的新线程的事件队列中获取InnerEvent事件。InnerEvent是EventHandler投递的事件。
EventHandler是一种用户在当前线程上投递InnerEvent事件到异步线程上处理的机制。每一个EventHandler和指定的EventRunner所创建的新线程绑定,并且该新线程内部有一个事件队列。EventHandler可以投递指定的InnerEvent事件到这个事件队列。EventRunner从事件队列里循环地取出事件,并在EventRunner所在线程执行processEvent回调。一般,EventHandler有两个主要作用:
-
在不同线程间分发和处理InnerEvent事件。
-
延迟处理InnerEvent事件。
运作机制
使用EventHandler实现线程间通信的主要流程:
-
EventHandler投递具体的InnerEvent事件到EventRunner所创建的线程的事件队列。
-
EventRunner循环从事件队列中获取InnerEvent事件。
-
新线程上处理该事件:触发InnerEvent的回调方法并触发EventHandler的处理方法。
接口说明
ohos.events.emitter(Emitter)
接口名 | 描述 |
---|---|
on(event: InnerEvent, callback: Callback<EventData>) | 持续订阅某个事件以及接收事件的回调处理。 |
once(event: InnerEvent, callback: Callback<EventData>) | 单次订阅某个事件以及接收事件的回调处理,接收到回调处理后自动取消订阅。 |
off(eventId: number) | 取消订阅某个事件。 |
emit(event: InnerEvent, data?: EventData) | 发送一个事件到事件队列。 |
InnerEvent
进程内的事件。
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
eventId | number | 是 | 是 | 事件的ID,由开发者定义用来辨别事件。 |
priority | EventPriority | 是 | 是 | 事件被投递的优先级。 |
EventData
发送事件时传递的数据。
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
data | [key:string]:any | 是 | 是 | 发送事件时传递的数据,数据类型支持字符串,整形和布尔型。 |
EventPriority
用于表示事件被投递的优先级
属性 | 描述 |
---|---|
Priority.IMMEDIATE | 表示事件被立即投递 |
Priority.HIGH | 表示事件先于LOW优先级投递 |
Priority.LOW | 表示事件优于IDLE优先级投递,事件的默认优先级是LOW |
Priority.IDLE | 表示在没有其他事件的情况下,才投递该事件 |
代码目录
类图
EventRunner:
EventRunner的create方法在创建Runner线程的同时会实例化一个EventQueue,并赋值给类内部的成员变量queue_ 。 EventRunner的Runner线程轮询queue_,取出队列中的InnerEvent事件,并处理该事件。
EventHandler:
EventHandler的各Send方法通过调用EventQueue的Insert方法将InnerEvent插入EventQueue的subEventQueues_中 或 idleEvents__ 中。
当调用Post方法,投递某个回调函数时,该回调函数会赋值给InnerEvent的taskCallback_,并通过Send方法将将拥有回调函数的InnerEvent插入队列。
其中,subEventQueues_是size为3的SubEventQueue的列表,3个SubEventQueue分别用于存储三种不同优先级(IMMEDIATE/HIGH/LOW)的InnerEvent。
idleEvents_用于存储优先级为IDLE的InnerEvent。
同理,Remove方法即从上述subEventQueue_ 或 idleEvent_ 中删除某事件。
EventQueue
通过成员变量 ioWaiter_ 取出定时或延时的InnerEvent事件。同时实现对文件描述符监听事件的回调。
ioWaiter_ 成员的类型默认使用NoneIoWaiter , 此时不支持文件描述符的监听。队列中的延时或定时事件的取出,通过NoneIoWaiter调用 std::condition_variable机制实现。
当EventHandler中的AddFileDescriptorListener被调用时,ioWaiter_成员的类型自动转换成EpollIoWaiter类型。EpollIoWaiter支持文件描述符的监听事件。此时,队列中的延时或定时事件的取出,通过系统的epoll机制实现。
关键代码摘录
EventRunner
EventQueue
EventHandler
更多原创内容请关注:深开鸿技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
