您现在的位置是:亿华云 > 数据库
HarmonyOS Sample 之 EventHandler 线程间通信
亿华云2025-10-09 01:36:20【数据库】8人已围观
简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com1.介绍在开发过程中,开发者经常需要在当前线程中处理下载任务等较为耗时的操作,但是又不希望
想了解更多内容,线程信请访问:
和华为官方合作共建的间通鸿蒙技术社区
https://harmonyos.51cto.com
1.介绍
在开发过程中,开发者经常需要在当前线程中处理下载任务等较为耗时的线程信操作,但是间通又不希望当前的线程受到阻塞。
此时,线程信就可以使用EventHandler机制。间通EventHandler是线程信HarmonyOS用于处理线程间通信的一种机制,
可以通过EventRunner创建新线程,间通将耗时的线程信操作放到新线程上执行。
这样既不阻塞原来的间通线程,任务又可以得到合理的线程信处理。比如:
主线程使用EventHandler创建子线程,间通子线程做耗时的线程信下载图片操作,下载完成后,间通子线程通过EventHandler通知主线程,线程信主线程再更新UI。
2.搭建环境
安装DevEco Studio,详情请参考DevEco Studio下载。
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。源码库
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
下载源码后,使用DevEco Studio 打开项目。
3.理论支持
EventRunner是一种事件循环器,循环处理队列中的 InnerEvent事件 或者 Runnable任务。
EventHandler是一种在 当前线程 上 投递 InnerEvent事件 或者 Runnable任务 到 异步线程上处理的机制。
InnerEvent是EventHandler投递的事件结构对象。
EventHandler和指定的EventRunner所创建的新线程绑定,并且该新线程内部有一个事件队列。
EventRunner的工作模式可以分为托管模式和手动模式。
投递时,EventHandler的优先级可在IMMEDIATE、HIGH、LOW、IDLE中选择。
详细请参考 线程间通信开发概述
使用EventHandler实现线程间通信的主要流程:
EventHandler投递具体的InnerEvent事件或者Runnable任务到EventRunner所创建的线程的事件队列。
EventRunner循环从事件队列中获取InnerEvent事件或者Runnable任务。
处理事件或任务:
如果EventRunner取出的云服务器提供商事件为InnerEvent事件,
则触发EventHandler的回调方法并触发EventHandler的处理方法,在新线程上处理该事件。
如果EventRunner取出的事件为Runnable任务,则EventRunner直接 在新线程上处理Runnable任务。
4.实例讲解
4.1.UI界面

4.2.后台代码
4.2.1 初始化EventRunner、EventHandler 对象
/** * 初始化对象 */ private void initHandler() { //创建事件运行器,默认是托管模式,create()的参数是false时,则为手动模式 eventRunner = EventRunner.create("TestRunner"); //初始化事件处理器,需要传入一个事件运行器 handler = new TestEventHandler(eventRunner); //第二个EventHandler myHandler=new MyEventHandler(eventRunner); }4.2.2 发送普通事件
/** * 发送一个普通事件 * @param component */ private void sendInnerEvent(Component component) { stringBuffer = new StringBuffer(); long param = 0L; //获取一个事件结构对象 //InnerEvent 对象包含一个额外的整数字段和一个额外的对象字段来携带特定数据。 InnerEvent normalInnerEvent = InnerEvent.get(EVENT_MESSAGE_NORMAL, param, null); InnerEvent delayInnerEvent = InnerEvent.get(EVENT_MESSAGE_DELAY, param, null); //发送事件,事件结构对象+事件等级 //IMMEDIATE:即时;IDLE:闲置;HIGH:高;LOW:低 handler.sendEvent(normalInnerEvent, EventHandler.Priority.IMMEDIATE); HiLog.debug(LABEL,"Send a NormalEvent done"); //发送一个延迟事件,事件结构对象+延迟时间+事件等级 handler.sendEvent(delayInnerEvent, DELAY_TIME, EventHandler.Priority.IMMEDIATE); HiLog.debug(LABEL,"Send a DelayEvent done"); }输出结果
09-09 12:14:36.512 14769-14769/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Send a NormalEvent done 09-09 12:14:36.512 14769-14769/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Send a DelayEvent done 09-09 12:14:36.512 14769-15211/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Received a NormalEvent 1631160876512 09-09 12:14:37.512 14769-15211/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Received a DelayEvent 16311608775124.2.3 发布可运行任务
/** * 发布可运行任务 * @param component */ private void postRunnableTask(Component component) { stringBuffer = new StringBuffer(); //任务1 //Runnable任务,将在EventRunner所在线程执行Runnable的run回调。 Runnable task1 = () -> { stringBuffer.append("Post runnableTask1 done").append(System.lineSeparator()); getUITaskDispatcher().asyncDispatch(() -> resultText.setText(stringBuffer.toString())); HiLog.debug(LABEL,"Post runnableTask1 done asyncDispatch"); }; //任务2 //Runnable任务,将在EventRunner所在线程执行Runnable的run回调。 Runnable task2 = () -> { stringBuffer.append("Post runnableTask2 done").append(System.lineSeparator()); getUITaskDispatcher().asyncDispatch(() -> resultText.setText(stringBuffer.toString())); HiLog.debug(LABEL,"Post runnableTask2 done asyncDispatch"); }; HiLog.debug(LABEL,"Main Task run1..."); //发布任务 myHandler.postTask(task1, EventHandler.Priority.IMMEDIATE); HiLog.debug(LABEL,"Main Task run2..."); //发布延迟任务,所以在task1后执行 myHandler.postTask(task2, DELAY_TIME, EventHandler.Priority.IMMEDIATE); HiLog.debug(LABEL,"Main Task run3..."); }输出结果
09-09 10:21:43.672 19863-19863/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Main Task run1... 09-09 10:21:43.672 19863-19863/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Main Task run2... 09-09 10:21:43.672 19863-19863/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Main Task run3... 09-09 10:21:43.673 19863-31145/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Post runnableTask1 done asyncDispatch 09-09 10:21:44.675 19863-31145/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Post runnableTask2 done asyncDispatch4.2.4 发送一个跨线程的事件
/** * 发送跨线程的事件 * @param component */ private void sendToOriginalThread(Component component) { stringBuffer = new StringBuffer(); long param = 0; //获取一个标志为跨线程的事件结构对象 InnerEvent innerEvent = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, eventRunner); //发送一个延迟事件 handler.sendEvent(innerEvent, DELAY_TIME, EventHandler.Priority.IMMEDIATE); HiLog.debug(LABEL,"send a CrossThreadAndDelayEvent done"+System.currentTimeMillis()); }输出结果
09-09 12:15:28.625 14769-14769/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: send a CrossThreadAndDelayEvent done1631160928625 09-09 12:15:29.626 14769-15211/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: Received a CrossThreadAndDelayEvent 1631160929626 09-09 12:15:29.626 14769-15211/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: send a ReplyEvent 1631160929626 09-09 12:15:29.626 14769-15211/ohos.samples.eventhandler D 00001/=>MainAbilitySlice: receive a ReplyEvent 16311609296264.2.5 继承事件处理器类,重写处理事件的方法
/** * 继承事件处理器类,b2b信息网重写处理事件的方法 */ private class TestEventHandler extends EventHandler { /** * 默认构造函数 * @param runner */ private TestEventHandler(EventRunner runner) { super(runner); } @Override public void processEvent(InnerEvent event) { switch (event.eventId) { case EVENT_MESSAGE_NORMAL: HiLog.debug(LABEL,"Received a NormalEvent "+System.currentTimeMillis()); stringBuffer.append("Received an innerEvent message").append(System.lineSeparator()); getUITaskDispatcher().asyncDispatch(() -> resultText.setText(stringBuffer.toString())); break; case EVENT_MESSAGE_DELAY: HiLog.debug(LABEL,"Received a DelayEvent "+System.currentTimeMillis()); stringBuffer.append("Received an innerEvent delay message").append(System.lineSeparator()); getUITaskDispatcher().asyncDispatch(() -> resultText.setText(stringBuffer.toString())); break; case EVENT_MESSAGE_CROSS_THREAD: HiLog.debug(LABEL,"Received a CrossThreadAndDelayEvent "+System.currentTimeMillis()); //接收事件对象 Object object = event.object; //判断对象类型 if (object instanceof EventRunner) { //将原先线程的EventRunner实例投递给新创建的线程 EventRunner runner = (EventRunner) object; // 将原先线程的EventRunner实例与新创建的线程的EventHandler绑定 EventHandler eventHandler = new EventHandler(runner) { @Override public void processEvent(InnerEvent innerEvent) { //需要在原先线程执行的操作 HiLog.debug(LABEL,"receive a ReplyEvent "+System.currentTimeMillis()); stringBuffer.append("OriginalThread receive a message"); getUITaskDispatcher().asyncDispatch(() -> resultText.setText(stringBuffer.toString())); } }; int testEventId = 1; long testParam = 0; //获取事件传递的参数 InnerEvent innerEvent = InnerEvent.get(testEventId, testParam, null); ///投递事件到原先的线程 eventHandler.sendEvent(innerEvent); HiLog.debug(LABEL,"send a ReplyEvent "+System.currentTimeMillis()); } break; default: break; } } }5.问题与思考
5.1 发布一个定时任务到队列,没有得到预期的效果。
//TODO 没有得到预期的效果 myHandler.postTimingTask(task1,System.currentTimeMillis()+1000L, EventHandler.Priority.IMMEDIATE);5.2 思考一下 示例中 哪个地方体现了 “一个EventRunner可以同时绑定多个EventHandler” 这句话?
6.完整代码
附件直接下载
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com
很赞哦!(41947)
热门文章
站长推荐
.com域名是国际最广泛流行的通用域名,目前全球注册量第一的域名,公司企业注册域名的首选。国际化公司通常会注册该类域名。
值得收藏!9个极好的SSD状态监控及性能优化工具
Tomcat 架构深度剖析:为什么它能扛住亿级流量?
大数据分析Java未来5年发展趋势
域后缀首选.com,.net,然后是.cn。后缀选择不当,导致流量损失。域名是企业与互联网网址之间的链接,关键是企业在网络上存在的标志。因此,选择好域名是开展网上工作的首要重要条件。
小米8 SE/9 SE安卓9 Pie内核源代码公布
JavaScript是如何工作的:JavaScript的共享传递和按值传递
Java帝国对Python的渗透能成功吗?