线程通信EventHandler使用(线程通信机制)
zhezhongyun 2025-07-23 19:22 5 浏览
作者:韩茹
公司:程序咖(北京)科技有限公司
鸿蒙巴士专栏作家
一、使用场景
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() {
// 待执行的操作,由开发者定义
}
};
- 投递Runnable任务,投递的优先级以IMMEDIATE为例,延时选择0ms和2ms。
// 优先级为immediate,延时0ms,该语句等价于同步投递myHandler.postSyncTask(task1,EventHandler.Priority.immediate);
myHandler.postTask(normalTask, 0, EventHandler.Priority.IMMEDIATE);
myHandler.postTask(delayTask, 2, EventHandler.Priority.IMMEDIATE);// 延时2ms后立即执行
- 启动和停止EventRunner,如果是托管模式,则不需要此步骤。
runner.run();
// 待执行操作
runner.stop();// 停止EventRunner
5.3 在新创建的线程里投递事件到原线程
EventHandler从新创建的线程投递事件到原线程并进行处理,开发步骤如下:
- 创建EventHandler的子类,在子类中重写实现方法processEvent()来处理事件。
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,以手动模式为例。
EventRunner runner = EventRunner.create(false);// create()的参数是true时,则为托管模式。
- 创建EventHandler子类的实例。
MyEventHandler myHandler = new MyEventHandler(runner);
- 获取InnerEvent事件。
// 获取事件实例,其属性eventId, param, object由开发者确定,代码中只是示例。
long param = 0L;
InnerEvent event = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, EventRunner.current());
- 投递事件,在新线程上直接处理。
// 将与当前线程绑定的EventRunner投递到与runner创建的新线程中
myHandler.sendEvent(event);
- 启动和停止EventRunner,如果是托管模式,则不需要此步骤。
runner.run();// 待执行操作
runner.stop();// 停止EventRunner
六、完整
非托管情况:
// 全局:
public static final int CODE_DOWNLOAD_FILE1 = 1;
public static final int CODE_DOWNLOAD_FILE2 = 2;
public static final int CODE_DOWNLOAD_FILE3 = 3;
// 线程A:
EventRunner runnerA = EventRunner.create(false);
runnerA.run(); // run之后一直循环卡在这里,所以需要新建一个线程run
// 线程B:
// 1.创建类继承EventHandler
public class MyEventHandler extends EventHandler {
private MyEventHandler(EventRunner runner) {
super(runner);
}
@Override
public void processEvent(InnerEvent event) {
super.processEvent(event);
if (event == null) {
return;
}
int eventId = event.eventId;
switch (eventId) {
case CODE_DOWNLOAD_FILE1: {
// 待执行的操作,由开发者定义
break;
}
case CODE_DOWNLOAD_FILE2: {
// 待执行的操作,由开发者定义
break;
}
case CODE_DOWNLOAD_FILE3: {
// 待执行的操作,由开发者定义
break;
}
default:
break;
}
}
}
// 2.创建MyEventHandler实例
MyEventHandler handler = new MyEventHandler(runnerA);
// 3.向线程A发送事件
handler.sendEvent(CODE_DOWNLOAD_FILE1);
handler.sendEvent(CODE_DOWNLOAD_FILE2);
handler.sendEvent(CODE_DOWNLOAD_FILE3);
// 4.runnerA不再使用后,退出
runnerA.stop();
托管情况:
// 全局:
public static final int CODE_DOWNLOAD_FILE1 = 1;
public static final int CODE_DOWNLOAD_FILE2 = 2;
public static final int CODE_DOWNLOAD_FILE3 = 3;
// 1.创建EventRunner A:
EventRunner runnerA = EventRunner.create("downloadRunner"); // 内部会新建一个线程
// 2.创建类继承EventHandler
public class MyEventHandler extends EventHandler {
private MyEventHandler(EventRunner runner) {
super(runner);
}
@Override
public void processEvent(InnerEvent event) {
super.processEvent(event);
if (event == null) {
return;
}
int eventId = event.eventId;
switch (eventId) {
case CODE_DOWNLOAD_FILE1: {
// 待执行的操作,由开发者定义
break;
}
case CODE_DOWNLOAD_FILE2: {
// 待执行的操作,由开发者定义
break;
}
case CODE_DOWNLOAD_FILE3: {
// 待执行的操作,由开发者定义
break;
}
default:
break;
}
}
}
// 3.创建MyEventHandler实例
MyEventHandler handler = new MyEventHandler(runnerA);
// 4.向线程A发送事件
handler.sendEvent(CODE_DOWNLOAD_FILE1);
handler.sendEvent(CODE_DOWNLOAD_FILE2);
handler.sendEvent(CODE_DOWNLOAD_FILE3);
// 5.runnerA没有任何对象引入时,线程会自动回收
runnerA = null;
七、示例代码
1、EventHandler投递InnerEvent事件
我们现在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:padding="20vp"
ohos:orientation="vertical">
<Button
ohos:id="$+id:btn1"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="EventHandler投递InnerEvent事件"
ohos:background_element="#eeeeee"
ohos:padding="20vp"
ohos:multiple_lines="true"
ohos:text_size="20fp"
ohos:margin="10vp"
/>
</DirectionalLayout>
然后在MainAbility中处理该按钮的点击事件,投递InnerEvent事件:
package com.example.hanrueventhandler.slice;
import com.example.hanrueventhandler.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
public class MainAbilitySlice extends AbilitySlice {
private static final int EVENT_MESSAGE_NORMAL = 1;
private static final int EVENT_MESSAGE_DELAY = 2;
// 定义日志标签
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
initComponent();
}
public void initComponent(){
findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> eventHandlerPostInnerEvent());
}
// 按钮1:EventHandler投递InnerEvent事件
public void eventHandlerPostInnerEvent(){
// 2.创建EventRunner,手动模式或者托管模式
EventRunner runner = EventRunner.create(true);// create()的参数是true时,则为托管模式
// 3.创建EventHandler子类的实例。
MyEventHandler myHandler = new MyEventHandler(runner);
// 4.获取InnerEvent事件。
// 获取事件实例,其属性eventId, param, object由开发者确定。
long param1 = 9527L;
Object object1 = "我是王二狗";
InnerEvent normalInnerEvent = InnerEvent.get(EVENT_MESSAGE_NORMAL, param1, object1);
long param2 = 1314L;
Object object2 = "鸿蒙巴士";
InnerEvent delayInnerEvent = InnerEvent.get(EVENT_MESSAGE_DELAY, param2, object2);
HiLog.info(LABEL," 。。。");
// 5.投递事件,投递的优先级以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后立即处理
// 6.启动和停止EventRunner,如果为托管模式,则不需要此步骤。
// runner.run();
// 待执行操作
// runner.stop();// 开发者根据业务需要在适当时机停止EventRunner
}
// 1.创建EventHandler的子类,在子类中重写实现方法processEvent()来处理事件。
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;
long param = event.param;
Object object = event.object;
HiLog.info(LABEL,"子线程。。。线程ID"+Thread.currentThread().getId()+",线程名称:"+Thread.currentThread().getName());
switch (eventId) {
case EVENT_MESSAGE_NORMAL:
// 待执行的操作,由开发者定义
HiLog.info(LABEL," 子线程中要处理的操作1。。。"+param+","+ object.toString());
break;
case EVENT_MESSAGE_DELAY:
// 待执行的操作,由开发者定义
HiLog.info(LABEL," 子线程中要处理的操作2。。。"+param+","+ object.toString());
break;
default:
break;
}
}
}
}
运行程序,并点击按钮1:
2、EventHandler投递Runnable任务
我们现在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:padding="20vp"
ohos:orientation="vertical">
...
<Button
ohos:id="$+id:btn2"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="EventHandler投递Runnable任务"
ohos:background_element="#eeeeee"
ohos:multiple_lines="true"
ohos:padding="20vp"
ohos:text_size="20fp"
ohos:margin="10vp"
/>
</DirectionalLayout>
然后在MainAbility中处理该按钮的点击事件,投递Runnable任务:
public void initComponent(){
findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> eventHandlerPostInnerEvent());
findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> eventHandlerPostRunnableTask());
}
// 2.EventHandler投递Runnable任务
public void eventHandlerPostRunnableTask(){
// 2.创建EventRunner,手动模式或者托管模式
EventRunner runner = EventRunner.create(true);// create()的参数是true时,则为托管模式
// 3.创建EventHandler子类的实例。
MyEventHandler myHandler = new MyEventHandler(runner);
// 4.创建Runnable任务。
Runnable normalTask = new Runnable() {
@Override
public void run() {
// 待执行的操作,由开发者定义
HiLog.info(LABEL,"子线程ID:"+Thread.currentThread().getId()+",子线程名称:"+Thread.currentThread().getName()+"--->Runnable的normalTask");
}
};
Runnable delayTask = new Runnable() {
@Override
public void run() {
// 待执行的操作,由开发者定义
HiLog.info(LABEL,"子线程ID:"+Thread.currentThread().getId()+",子线程名称:"+Thread.currentThread().getName()+"--->Runnable的delayTask");
}
};
HiLog.info(LABEL," 。。。。。。");
// 5.投递
// 优先级为immediate,延时0ms,该语句等价于同步投递myHandler.postSyncTask(task1,EventHandler.Priority.immediate);
myHandler.postTask(normalTask, 0, EventHandler.Priority.IMMEDIATE);
myHandler.postTask(delayTask, 2, EventHandler.Priority.IMMEDIATE);// 延时2ms后立即执行
// 6.启动和停止EventRunner,如果为托管模式,则不需要此步骤。
// runner.run();
// 待执行操作
// runner.stop();// 停止EventRunner
}
运行程序,并点击按钮2:
3、在新创建的线程里投递事件到原线程
我们现在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:padding="20vp"
ohos:orientation="vertical">
...
<Button
ohos:id="$+id:btn3"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="在新创建的线程里投递事件到原线程"
ohos:background_element="#eeeeee"
ohos:padding="20vp"
ohos:multiple_lines="true"
ohos:text_size="20fp"
ohos:margin="10vp"
/>
</DirectionalLayout>
然后在MainAbility中处理该按钮的点击事件,在新创建的线程里投递事件到原线程:
public void initComponent(){
findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> eventHandlerPostInnerEvent());
findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> eventHandlerPostRunnableTask());
findComponentById(ResourceTable.Id_btn3).setClickedListener(component -> postInnerEventToOriginalThread());
}
// 3.在新创建的线程里投递事件到原线程
public void postInnerEventToOriginalThread(){
// 2.创建EventRunner,手动模式或者托管模式
EventRunner runner = EventRunner.create(true);// create()的参数是true时,则为托管模式
// 3.创建EventHandler子类的实例。
MyEventHandler myHandler = new MyEventHandler(runner);
// 4.获取InnerEvent事件。
// 获取事件实例,其属性eventId, param, object由开发者确定。
long param = 723L;
// 注意:这里的第三个参数Object,要传入当前线程对象。
InnerEvent event = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, EventRunner.current());
// 5.投递事件,将与当前线程绑定的EventRunner投递到与runner创建的新线程中
myHandler.sendEvent(event);
// 6.启动和停止EventRunner,如果为托管模式,则不需要此步骤。
// runner.run();
// 待执行操作
// runner.stop();// 开发者根据业务需要在适当时机停止EventRunner
}
然后我们在MyEventHandler中,再加一个case进行处理:
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;
long param = event.param;
Object object = event.object;
HiLog.info(LABEL,"子线程。。。线程ID"+Thread.currentThread().getId()+",线程名称:"+Thread.currentThread().getName());
switch (eventId) {
case EVENT_MESSAGE_NORMAL:
// 待执行的操作,由开发者定义
break;
case EVENT_MESSAGE_DELAY:
// 待执行的操作,由开发者定义
break;
case EVENT_MESSAGE_CROSS_THREAD:
if (object instanceof EventRunner) {
HiLog.info(LABEL," 子线程中要处理的操作3。。。"+param+","+ object.toString());
// 将原先线程的EventRunner实例投递给新创建的线程
EventRunner runner2 = (EventRunner) object;
// 将原先线程的EventRunner实例与新创建的线程的EventHandler绑定
EventHandler myHandler2 = new EventHandler(runner2) {
@Override
public void processEvent(InnerEvent event) {
// 需要在原先线程执行的操作
HiLog.info(LABEL," 原先的线程。。。"+Thread.currentThread().getId()+","+Thread.currentThread().getName());
HiLog.info(LABEL," 原先的线程。。。eventId"+event.eventId+",param:"+event.param+",object:"+event.object);
}
};
int eventId2 = 1;
long param2 = 9988L;
Object object2 = "我是小白菜";
InnerEvent event2 = InnerEvent.get(eventId2, param2, object2);
myHandler2.sendEvent(event2); // 投递事件到原先的线程
}
break;
default:
break;
}
}
}
运行程序,并点击按钮3:
相关推荐
- Trump Pushes for 15%-20% Minimum Tariffs on EU, Sticks to Auto Duties: Report
-
TMTPOST--U.S.PresidentDonaldTrumpistakingatougherstanceduringtradenegotiationswiththe...
- Note-15.使用A4988控制步进电机(dvp15mc11t控制步进电机)
-
如果需要控制一堆步进电机,那么只使用一个Arduino来控制,就会占用大量的处理时间,而无法处理其他事情,除非使用一个独立的专用步进电机驱动器:A4988。A4988只需两个引脚就可以控制双极步进电机...
- Negotiated settlement, not sanctions, the right way to end the Ukraine crisis
-
Negotiatedsettlement,notsanctions,therightwaytoendtheUkrainecrisis:ChinaDailyeditorial...
- U.S. Services May be Added to EU's Retaliatory Target List as More Members Seek Powerful Trade Tool If Talks Fail
-
TMTPOST--AmericanservicescouldbeaddedtotheEuropeanUnion’sretaliatorytargetlist,highlig...
- S7-1200伺服指令运动指令(s71200伺服位置控制实例)
-
1.MC_Halt指令名称:停止轴运行指令功能:停止所有运动并以组态的减速度停止轴。使用技巧:常用MC_Halt指令来停止通过MC_MoveVelocity指令触发的轴的运行。『注意』部分输入/输出管...
- Deepseek太强了!等了10年的Excel模糊下拉,竟然5分钟就搞定了
-
今天跟大家分享下我们如何通过Deepseek来编写VBA代码,制作模糊搜索的下拉菜单,这个等来十来年的功能,用Deepseek竟然几分钟就搞定了,不得不感叹AI工具的强大,我们以后能干的过AI吗,这真...
- 7.Unity物理关节(unity物理骨骼)
-
7.物理关节Unity的物理关节组件将刚体连接到另一个刚体或空间中的固定点。施加使刚体移动的力,关节限制可以限制移动。关节赋予刚体一定的自由度,从而使这些刚体具有不同的运动。Unity提供的物理关...
- 西门子111报文对应FB284引脚(西门子111报文详解)
-
西门子FB284是基于111报文的功能块,使用FB284比较方便,直接调用就可以控制V90伺服的定位控制。下面是整理的FB284对应的111报文。便于理解FB284功能块,更方面应用在实际项目中。11...
- 数据质量动态探查及相关前端实现(数据质量改进实践指南)
-
需求背景数据探查上线之前,数据验证都是通过写SQL方式进行查询的,从编写SQL,到解析运行出结果,不仅时间长,还会反复消耗计算资源,探查上线后,只需要一次探查,就可以得到整张表的探查报告,但后续...
- 阿里面试官:你连个排序算法都讲不明白?出门右拐吧
-
排序算法一表总览其他注意事项:计数排序中,kkk是整数的范围稳定性是指,序列中相同的数是否有可能交换顺序,例如序列中有两个8,顺序为888和8′8^{'}8′,如果在排序完之后,顺序有...
- 直流电机速度、位置双环控制简明教程
-
速度、位置的双环控制是我们在电机的控制系统中常用的方法,很实用。下面让我们来看一下内部实现的原理。1.速度闭环控制我们一般在速度闭环控制系统里面,使用增量式PI控制。而在我们的微处理器里面,因为控制器...
- 纳米机器人的精准定位与导航(纳米机器人怎么控制位置)
-
纳米机器人的精准定位与导航涉及多学科交叉技术,其“源码”(控制逻辑与算法)需结合硬件特性、环境感知和执行器设计。以下从控制原理、算法逻辑、关键技术实现等方面提供概念性思路(非实际可运行代码),供技术探...
- C语言进阶教程:多级指针的应用(c语言一级指针和二级指针)
-
在C语言中,指针可以指向变量的地址。多级指针(PointerstoPointers或MultilevelPointers)则是指向另一个指针地址的指针。这种概念可以扩展到任意级别(二级指针、...
- 被 Trac 的文件整理能力圈粉了!这 “香” 气挡不住
-
前阵子整理电脑文件夹时,我遇到了个麻烦:上千个文档和照片,要是手动一个个重命名、分类,不仅手得点到发麻,估计还得耗上一上午。于是我就琢磨着,能不能找个办法实现一键批量重命名。我先在网上搜了些批量改名软...
- Enhancer-轻量化的字节码增强组件包
-
一、问题描述当我们的业务发展到一定阶段的时候,系统的复杂度往往会非常高,不再是一个简单的单体应用所能够承载的,随之而来的是系统架构的不断升级与演变。一般对于大型的ToC的互联网企业来说,整个系统都是...
- 一周热门
- 最近发表
-
- Trump Pushes for 15%-20% Minimum Tariffs on EU, Sticks to Auto Duties: Report
- Note-15.使用A4988控制步进电机(dvp15mc11t控制步进电机)
- Negotiated settlement, not sanctions, the right way to end the Ukraine crisis
- U.S. Services May be Added to EU's Retaliatory Target List as More Members Seek Powerful Trade Tool If Talks Fail
- S7-1200伺服指令运动指令(s71200伺服位置控制实例)
- Deepseek太强了!等了10年的Excel模糊下拉,竟然5分钟就搞定了
- 7.Unity物理关节(unity物理骨骼)
- 西门子111报文对应FB284引脚(西门子111报文详解)
- 数据质量动态探查及相关前端实现(数据质量改进实践指南)
- 阿里面试官:你连个排序算法都讲不明白?出门右拐吧
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)
- CSS 水平对齐 (Horizontal Align) (30)
- opacity 属性 (32)