作者:韩茹
公司:程序咖(北京)科技有限公司
鸿蒙巴士专栏作家
一、应用场景
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: