作者:韩茹
公司:程序咖(北京)科技有限公司
鸿蒙巴士专栏作家
一、使用场景
EventHandler开发场景
EventHandler的主要功能是将InnerEvent事件或者Runnable任务投递到其他的线程进行处理,其使用的场景包括:
- 开发者需要将InnerEvent事件投递到新的线程,按照优先级和延时进行处理。投递时,EventHandler的优先级可在IMMEDIATE、HIGH、LOW、IDLE中选择,并设置合适的delayTime。
- 开发者需要将Runnable任务投递到新的线程,并按照优先级和延时进行处理。投递时,EventHandler的优先级可在IMMEDIATE、HIGH、LOW、IDLE中选择,并设置合适的delayTime。
- 开发者需要在新创建的线程里投递事件到原线程进行处理。
EventRunner工作模式
EventRunner的工作模式可以分为托管模式和手动模式。两种模式是在调用EventRunner的create()方法时,通过选择不同的参数来实现的,详见API参考。默认为托管模式。
- 托管模式:不需要开发者调用run()和stop()方法去启动和停止EventRunner。当EventRunner实例化时,系统调用run()来启动EventRunner;当EventRunner不被引用时,系统调用stop()来停止EventRunner。
- 手动模式:需要开发者自行调用EventRunner的run()方法和stop()方法来确保线程的启动和停止。
二、EventHandler
EventHandler,允许在异步线程上发送和处理InnerEvent和Runnable对象。每个EventHandler实例都绑定一个线程,该线程有一个事件队列。线程周期性地从事件队列中检索事件,并将事件分派给EventHandler进行处理。EventHandler将事件或Runnable任务传递到线程的事件队列,并在事件或任务从事件队列中出来时执行它。
您可以使用EventHandler在不同的线程之间调度和处理事件和Runnable 对象,并将事件或Runnable 对象安排在特定的时间间隔内进行处理。
您可以使用此类中提供的方法发送同步或异步事件、延迟事件处理以及设置事件优先级。
您需要重写processEvent(ohos.eventhandler.InnerEvent)方法来处理事件。
EventHandler类的定义:
java.lang.Object
|---ohos.eventhandler.EventHandler
public class EventHandler extends Object
EventHandler的属性Priority(优先级)介绍:
EventRunner将根据优先级的高低从事件队列中获取事件或者Runnable任务进行处理。
| 属性 | 描述 |
|---|---|
| Priority.IMMEDIATE | 表示事件被立即投递 |
| Priority.HIGH | 表示事件先于LOW优先级投递 |
| Priority.LOW | 表示事件优于IDLE优先级投递,事件的默认优先级是LOW |
| Priority.IDLE | 表示在没有其他事件的情况下,才投递该事件 |
EventHandler的主要方法介绍:
| 接口名 | 描述 |
|---|---|
| EventHandler(EventRunner runner) | 利用已有的EventRunner来创建EventHandler |
| current() | 在processEvent回调中,获取当前的EventHandler |
| processEvent(InnerEvent event) | 回调处理事件,由开发者实现 |
| sendEvent(InnerEvent event) | 发送一个事件到事件队列,延时为0ms, 优先级为LOW |
| sendEvent(InnerEvent event, long delayTime) | 发送一个延时事件到事件队列,优先级为LOW |
| sendEvent(InnerEvent event, long delayTime, EventHandler.Priority priority) | 发送一个指定优先级的延时事件到事件队列 |
| sendEvent(InnerEvent event, EventHandler.Priority priority) | 发送一个指定优先级的事件到事件队列,延时为0ms |
| sendSyncEvent(InnerEvent event) | 发送一个同步事件到事件队列,延时为0ms,优先级为LOW |
| sendSyncEvent(InnerEvent event, EventHandler.Priority priority) | 发送一个指定优先级的同步事件到事件队列,延时为0ms,优先级不可以是IDLE |
| postSyncTask(Runnable task) | 发送一个Runnable同步任务到事件队列,延时为0ms, 优先级为LOW |
| postSyncTask(Runnable task, EventHandler.Priority priority) | 发送一个指定优先级的Runnable同步任务到事件队列,延时为0ms |
| postTask(Runnable task) | 发送一个Runnable任务到事件队列,延时为0ms,优先级为LOW |
| postTask(Runnable task, long delayTime) | 发送一个Runnable延时任务到事件队列,优先级为LOW |
| postTask(Runnable task, long delayTime, EventHandler.Priority priority) | 发送一个指定优先级的Runnable延时任务到事件队列 |
| postTask(Runnable task, EventHandler.Priority priority) | 发送一个指定优先级的Runnable任务到事件队列,延时为0ms |
| sendTimingEvent(InnerEvent event, long taskTime) | 发送一个定时事件到队列,在taskTime时间执行,如果taskTime小于当前时间,立即执行,优先级为LOW |
| sendTimingEvent(InnerEvent event, long taskTime, EventHandler.Priority priority) | 发送一个带优先级的事件到队列,在taskTime时间执行,如果taskTime小于当前时间,立即执行 |
| postTimingTask(Runnable task, long taskTime) | 发送一个Runnable任务到队列,在taskTime时间执行,如果taskTime小于当前时间,立即执行,优先级为LOW |
| postTimingTask(Runnable task, long taskTime, EventHandler.Priority priority) | 发送一个带优先级的Runnable任务到队列,在taskTime时间执行,如果taskTime小于当前时间,立即执行 |
| removeEvent(int eventId) | 删除指定id的事件 |
| removeEvent(int eventId, long param) | 删除指定id和param的事件 |
| removeEvent(int eventId, long param, Object object) | 删除指定id、param和object的事件 |
| removeAllEvent() | 删除该EventHandler的所有事件 |
| getEventName(InnerEvent event) | 获取事件的名字 |
| getEventRunner() | 获取该EventHandler绑定的EventRunner |
| isIdle() | 判断队列是否为空 |
| hasInnerEvent(Runnable runnable) | 根据指定的runnable参数,检查是否有还未被处理的任务。可以根据不同的入参进行检查,详见EventHandler |
三、EventRunner
EventRunner,在当前线程中创建和管理事件队列。
调用run()方法后,EventRunner将从事件队列中连续检索事件,并将事件分派给匹配的EventHandler。然后将调用EventHandler#processEvent(InnerEvent)方法来处理事件。
EventRunner类定义。
java.lang.Object
|---ohos.eventhandler.EventRunner
public final class EventRunner extends Object
EventRunner的主要方法介绍:
| 接口名 | 描述 |
|---|---|
| create() | 创建一个拥有新线程的EventRunner |
| create(boolean inNewThread) | 创建一个拥有新线程的EventRunner,inNewThread为true时,EventRunner为托管模式,系统将自动管理该EventRunner;inNewThread为false时,EventRunner为手动模式 |
| create(String newThreadName) | 创建一个拥有新线程的EventRunner, 新线程的名字是 newThreadName |
| current() | 获取当前线程的EventRunner |
| run() | EventRunner为手动模式时,调用该方法启动新的线程 |
| stop() | EventRunner为手动模式时,调用该方法停止新的线程 |
四、InnerEvent
InnerEvent,用于定义可以发送到EventHandler的事件的结构。
InnerEvent类的定义:
public final class InnerEvent
extends Object
implements Sequenceable
一个InnerEvent 对象,包含了一个额外的整数字段和一个额外的对象字段来携带特定数据。
InnerEvent的属性介绍:
| 属性 | 描述 |
|---|---|
| eventId | 事件的ID, 由开发者定义用来辨别事件 |
| object | 事件携带的Object信息 |
| param | 事件携带的long型数据 |
InnerEvent的构造函数是私有的。因此,需要调用get()方法来创建InnerEvent实例。该方法将从回收对象池中提取InnerEvent实例。
常用方法:
| 方法名 | 描述 |
|---|---|
| drop() | 释放一个事件实例 |
| get() | 获得一个事件实例 |
| get(int eventId) | 获得一个指定的eventId的事件实例 |
| get(int eventId, long param) | 获得一个指定的eventId和param的事件实例 |
| get(int eventId, long param, Object object) | 获得一个指定的eventId,param和object的事件实例 |
| get(int eventId, Object object) | 获得一个指定的eventId和object的事件实例 |
| PacMap getPacMap() | 获取PacMap,如果没有,会新建一个 |
| Runnable getTask() | 获取Runnable任务 |
| PacMap peekPacMap() | 获取PacMap |
| void setPacMap(PacMap pacMap) | 设置PacMap |
更多方法请查看,官方API
五、流程逻辑
5.1 EventHandler投递InnerEvent事件
EventHandler投递InnerEvent事件,并按照优先级和延时进行处理,开发步骤如下:
- 创建EventHandler的子类,在子类中重写实现方法processEvent()来处理事件。
private static final int EVENT_MESSAGE_NORMAL = 1;
private static final int EVENT_MESSAGE_DELAY = 2;
private class MyEventHandler extends EventHandler {
private MyEventHandler(EventRunner runner) {
super(runner);
}
// 重写实现processEvent方法
@Override
public void processEvent(InnerEvent event) {
super.processEvent(event);
if (event == null) {
return;
}
int eventId = event.eventId;
switch (eventId) {
case EVENT_MESSAGE_NORMAL:
// 待执行的操作,由开发者定义
break;
case EVENT_MESSAGE_DELAY:
// 待执行的操作,由开发者定义
break;
default:
break;
}
}
}
- 创建EventRunner,以手动模式为例。
EventRunner runner = EventRunner.create(false);// create()的参数是true时,则为托管模式
- 创建EventHandler子类的实例。
MyEventHandler myHandler = new MyEventHandler(runner);
- 获取InnerEvent事件。
// 获取事件实例,其属性eventId, param, object由开发者确定,代码中只是示例。
long param = 0L;
Object object = null;
InnerEvent normalInnerEvent = InnerEvent.get(EVENT_MESSAGE_NORMAL, param, object);
InnerEvent delayInnerEvent = InnerEvent.get(EVENT_MESSAGE_DELAY, param, object);
- 投递事件,投递的优先级以IMMEDIATE为例,延时选择0ms和2ms。
// 优先级IMMEDIATE,投递之后立即处理,延时为0ms,该语句等价于同步投递sendSyncEvent(event1,EventHandler.Priority.IMMEDIATE);
myHandler.sendEvent(normalInnerEvent, 0, EventHandler.Priority.IMMEDIATE);
myHandler.sendEvent(delayInnerEvent, 2, EventHandler.Priority.IMMEDIATE); // 延时2ms后立即处理
- 启动和停止EventRunner,如果为托管模式,则不需要此步骤。
runner.run();// 待执行操作runner.stop();// 开发者根据业务需要在适当时机停止EventRunner
5.2 EventHandler投递Runnable任务
EventHandler投递Runnable任务,并按照优先级和延时进行处理,开发步骤如下:
-
创建EventHandler的子类,创建EventRunner,并创建EventHandler子类的实例,步骤与EventHandler投递InnerEvent场景的步骤1-3相同。
-
创建Runnable任务。
Runnable normalTask = new Runnable() {
@Override
public void run() {
// 待执行的操作,由开发者定义
}
};
Runnable delayTask = new Runnable() {
@Override
public void run() {
// 待执行的操作

本文介绍了EventHandler在Android鸿蒙系统中如何在不同场景下投递InnerEvent和Runnable任务,包括优先级控制、延时处理和线程间通信。详细讲解了EventRunner的工作模式,以及如何在新线程中跨线程投递事件。

2112

被折叠的 条评论
为什么被折叠?



