HarmonyOS鸿蒙Next之线程02——EventHandler处理线程间通信
HarmonyOS鸿蒙Next之线程02——EventHandler处理线程间通信
创建一个名为EventHandler
的Car
设备类型的任务,用于演示EventHandler
处理线程间通信的使用。
事件循环器
大家如果有开发Netty或者Node.js应用的话,那么对于事件循环器就不大陌生了,事件循环器是高并发非阻塞的“秘笈”。在HarmonyOS中,事件循环器实现方式就是EventHandler
机制。当前线程中处理较为耗时的操作时,如果不希望当前的线程受到阻塞。此时,就可以使用EventHandler
机制。EventHandler
是HarmonyOS用于处理线程间通信的一种机制,可以通过EventRunner
创建新线程,将耗时的操作放到新线程上执行。这样既不阻塞原来的线程,任务又可以得到合理的处理。比如:主线程使用EventHandler
创建子线程,子线程做耗时的下载图片操作,下载完成后,子线程通过EventHandler
通知主线程,主线程再更新UI。
Netty或者Node.js方面的内容,可以参见本文最后引用部分。
修改ability_main.xml
修改ability_main.xml
内容如下:
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical">
<Text
ohos:id="$+id:text_send_event"
ohos:height="match_parent"
ohos:width="match_content"
ohos:background_element="$graphic:background_ability_main"
ohos:layout_alignment="horizontal_center"
ohos:text="Send Event"
ohos:text_size="50" />
</DirectionalLayout>
显示界面效果如下图1所示
自定义事件处理器
MyEventHandler
是自定义的一个事件处理。该事件处理器逻辑比较简单,只是模拟了一个耗时的操作。
package com.waylau.hmos.eventhandler;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import java.util.concurrent.TimeUnit;
public class MyEventHandler extends EventHandler {
private static final String TAG = MyEventHandler.class.getSimpleName();
private static final HiLogLabel LABEL_LOG =
new HiLogLabel(HiLog.LOG_APP, 0x00001, TAG);
public MyEventHandler(EventRunner runner) throws IllegalArgumentException {
super(runner);
}
@Override
public void processEvent(InnerEvent event) {
super.processEvent(event);
if (event == null) {
HiLog.info(LABEL_LOG, "before processEvent event is null");
return;
}
int eventId = event.eventId;
HiLog.info(LABEL_LOG, "before processEvent eventId: %{public}s", eventId);
int task1Result = getRandomInt();
try {
// 模拟一个耗时的操作
TimeUnit.MILLISECONDS.sleep(task1Result);
} catch (InterruptedException e) {
e.printStackTrace();
}
HiLog.info(LABEL_LOG, "after processEvent eventId %{public}s", eventId);
}
// 返回随机整数
private int getRandomInt() {
// 获取[0, 1000)之间的int整数。方法如下:
double a = Math.random();
int result = (int) (a * 1000);
return result;
}
}
这个耗时操作,是通过获取一个随机数,而后根据随机数执行线程sleep实现的。
执行事件发送
修改MainAbilitySlice
,增加事件发送相关的逻辑。
package com.waylau.hmos.eventhandler.slice;
import com.waylau.hmos.eventhandler.MyEventHandler;
import com.waylau.hmos.eventhandler.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Text;
import ohos.eventhandler.EventRunner;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
public class MainAbilitySlice extends AbilitySlice {
private static final String TAG = MainAbilitySlice.class.getSimpleName();
private static final HiLogLabel LABEL_LOG =
new HiLogLabel(HiLog.LOG_APP, 0x00001, TAG);
private EventRunner eventRunner = EventRunner.create("MyEventRunner"); // 内部会新建一个线程
private int eventId = 0; // 事件ID,递增的序列
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Text textSendEvent =
(Text) findComponentById(ResourceTable.Id_text_send_event);
textSendEvent.setClickedListener(listener -> sendEvent());
}
private void sendEvent() {
HiLog.info(LABEL_LOG, "before sendEvent");
MyEventHandler handler = new MyEventHandler(eventRunner);
eventId++;
handler.sendEvent(eventId);
HiLog.info(LABEL_LOG, "end sendEvent eventId: %{public}s", eventId);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
上述代码,
Text
增加了点击事件,以触发sendEvent
任务sendEvent
方法中创建了EventHandler
事件处理器- 通过
EventHandler
的sendEvent
方法发送了一个事件ID。事件ID是自增的序列。
运行
运行应用后,点击3次界面文本“Start Event”以触发事件派发。此时,控制台输出如下:
01-15 14:47:05.056 3943-3943/com.waylau.hmos.eventhandler I 00001/MainAbilitySlice: before sendEvent
01-15 14:47:05.057 3943-3943/com.waylau.hmos.eventhandler I 00001/MainAbilitySlice: end sendEvent eventId: 1
01-15 14:47:05.058 3943-4024/com.waylau.hmos.eventhandler I 00001/MyEventHandler: before processEvent eventId: 1
01-15 14:47:05.196 3943-4024/com.waylau.hmos.eventhandler I 00001/MyEventHandler: after processEvent eventId 1
01-15 14:47:07.731 3943-3943/com.waylau.hmos.eventhandler I 00001/MainAbilitySlice: before sendEvent
01-15 14:47:07.732 3943-4024/com.waylau.hmos.eventhandler I 00001/MyEventHandler: before processEvent eventId: 2
01-15 14:47:07.732 3943-3943/com.waylau.hmos.eventhandler I 00001/MainAbilitySlice: end sendEvent eventId: 2
01-15 14:47:08.104 3943-4024/com.waylau.hmos.eventhandler I 00001/MyEventHandler: after processEvent eventId 2
01-15 14:47:09.149 3943-3943/com.waylau.hmos.eventhandler I 00001/MainAbilitySlice: before sendEvent
01-15 14:47:09.151 3943-3943/com.waylau.hmos.eventhandler I 00001/MainAbilitySlice: end sendEvent eventId: 3
01-15 14:47:09.159 3943-4024/com.waylau.hmos.eventhandler I 00001/MyEventHandler: before processEvent eventId: 3
01-15 14:47:09.300 3943-4024/com.waylau.hmos.eventhandler I 00001/MyEventHandler: after processEvent eventId 3
分别执行了3次可以看到MainAbilitySlice
先是发送了事件,而后MyEventHandler
就处理了事件。
参考引用
- 更多示例源码,见《跟老卫学HarmonyOS》 https://github.com/waylau/harmonyos-tutorial
- 《Netty原理解析与开发实战》 https://item.jd.com/13072504.html
- 《Node.js企业级应用开发实战》 https://item.jd.com/12924544.html
子线程通过EventHandler通知主线程,主线程再更新UI。这个内容呢?只是发了事件,处理完成后的数据更新到UI线程呢,不能搞个完整的例子吗?
更多关于HarmonyOS鸿蒙Next之线程02——EventHandler处理线程间通信的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
似乎挺难的,无奈了
一直觉得这内容有内涵
一起顶,让更多的人看到
这才是我需要的,谢谢你的分享
如何吃透,交个方法
楼主真是见多识广啊,懂的好多
膜拜呀,请接受我的膝盖
在HarmonyOS中,EventHandler
是用于处理线程间通信的核心机制之一。它允许开发者在不同线程之间传递消息并执行相应的任务。EventHandler
基于事件驱动模型,通过消息队列实现线程间的异步通信。
EventHandler
的主要功能包括:
- 消息发送:通过
sendEvent
或postEvent
方法将消息发送到目标线程的消息队列中。 - 消息处理:在目标线程中,
EventHandler
会从消息队列中取出消息,并调用相应的回调函数进行处理。 - 线程切换:
EventHandler
可以确保消息在指定的线程中执行,从而实现线程切换。
使用EventHandler
时,开发者需要创建一个继承自EventHandler
的类,并重写processEvent
方法以处理接收到的消息。通过EventRunner
创建并启动一个事件循环,EventHandler
会绑定到该事件循环上,从而在指定的线程中处理消息。
示例代码:
import { EventHandler, EventRunner, Event } from '@ohos.eventhandler';
class MyEventHandler extends EventHandler {
processEvent(event: Event): void {
// 处理接收到的消息
console.log("Received event:", event.eventId);
}
}
// 创建事件循环
let runner = new EventRunner();
let handler = new MyEventHandler(runner);
// 发送消息
let event = new Event(1); // 1为事件ID
handler.sendEvent(event);
EventHandler
适用于需要在不同线程间传递消息并执行任务的场景,如UI线程与后台线程的通信。通过EventHandler
,开发者可以简化线程间通信的复杂性,提高代码的可维护性和可读性。
在HarmonyOS鸿蒙Next中,EventHandler
是用于处理线程间通信的核心组件。它允许开发者在不同线程之间传递消息和执行任务,确保UI线程的流畅性。通过EventHandler
,开发者可以将耗时操作放在后台线程执行,完成后通过消息机制通知UI线程更新界面。EventHandler
提供了sendMessage
、postTask
等方法,支持异步消息传递和任务调度,有效避免了线程阻塞和资源竞争问题,提升了应用的响应速度和稳定性。