鸿蒙线程通讯EventHandler介绍
在开发过程中,开发者经常需要在当前线程中处理下载任务等较为耗时的操作,但是又不希望当前的线程受到阻塞。此时,就可以使用EventHandler机制。EventHandler是HarmonyOS用于处理线程间通信的一种机制,可以通过EventRunner创建新线程,将耗时的操作放到新线程上执行。这样既不阻塞原来的线程,任务又可以得到合理的处理。比如:主线程使用EventHandler创建子线程,子线程做耗时的下载图片操作,下载完成后,子线程通过EventHandler通知主线程,主线程再更新UI。
基本概念
EventRunner是一种事件循环器,循环处理从该EventRunner创建的新线程的事件队列中获取InnerEvent事件或者Runnable任务。InnerEvent是EventHandler投递的事件。
EventHandler是一种用户在当前线程上投递InnerEvent事件或者Runnable任务到异步线程上处理的机制。每一个EventHandler和指定的EventRunner所创建的新线程绑定,并且该新线程内部有一个事件队列。EventHandler可以投递指定的InnerEvent事件或Runnable任务到这个事件队列。EventRunner从事件队列里循环地取出事件,如果取出的事件是InnerEvent事件,将在EventRunner所在线程执行processEvent回调;如果取出的事件是Runnable任务,将在EventRunner所在线程执行Runnable的run回调。一般,EventHandler有两个主要作用:
- 在不同线程间分发和处理InnerEvent事件或Runnable任务。
- 延迟处理InnerEvent事件或Runnable任务。
运作机制
EventHandler的运作机制如下图所示:

使用EventHandler实现线程间通信的主要流程:
- EventHandler投递具体的InnerEvent事件或者Runnable任务到EventRunner所创建的线程的事件队列。
- EventRunner循环从事件队列中获取InnerEvent事件或者Runnable任务。
- 处理事件或任务:
- 如果EventRunner取出的事件为InnerEvent事件,则触发EventHandler的回调方法并触发EventHandler的处理方法,在新线程上处理该事件。
- 如果EventRunner取出的事件为Runnable任务,则EventRunner直接在新线程上处理Runnable任务。
约束限制
- 在进行线程间通信的时候,EventHandler只能和EventRunner所创建的线程进行绑定,EventRunner创建时需要判断是否创建成功,只有确保获取的EventRunner实例非空时,才可以使用EventHandler绑定EventRunner。
- 一个EventHandler只能同时与一个EventRunner绑定,一个EventRunner可以同时绑定多个EventHandler。
应用例子:
EventHandler从新创建的线程投递事件到原线程并进行处理,开发步骤如下:
private static final int EVENT_MESSAGE_CROSS_THREAD = 1;
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_CROSS_THREAD:
Object object = event.object;
if (object instanceof EventRunner) {
// 将原先线程的EventRunner实例投递给新创建的线程
EventRunner runner2 = (EventRunner) object;
// 将原先线程的EventRunner实例与新创建的线程的EventHandler绑定
EventHandler myHandler2 = new EventHandler(runner2) {
@Override
public void processEvent(InnerEvent event) {
// 需要在原先线程执行的操作
}
};
int eventId2 = 1;
long param2 = 0L;
Object object2 = null;
InnerEvent event2 = InnerEvent.get(eventId2, param2, object2);
myHandler2.sendEvent(event2); // 投递事件到原先的线程
}
break;
default:
break;
}
}
}
EventRunner runner = EventRunner.create(false);// create()的参数是true时,则为托管模式。
MyEventHandler myHandler = new MyEventHandler(runner);
long param = 0L;
InnerEvent event = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, EventRunner.current());
// 将与当前线程绑定的EventRunner投递到与runner创建的新线程中
myHandler.sendEvent(event);
阅读原文