HarmonyOS中的多线程应用 原创
目录
本篇记录的是在HarmonyOS中跨线程更新UI
EventRunner是一种事件循环器,循环处理从该EventRunner创建的新线程的事件队列中获取InnerEvent事件或者Runnable任务。InnerEvent是EventHandler投递的事件。
EventHandler是一种用户在当前线程上投递InnerEvent事件或者Runnable任务到异步线程上处理的机制。每一个EventHandler和指定的EventRunner所创建的新线程绑定,并且该新线程内部有一个事件队列。EventHandler可以投递指定的InnerEvent事件或Runnable任务到这个事件队列。EventRunner从事件队列里循环地取出事件,如果取出的事件是InnerEvent事件,将在EventRunner所在线程执行processEvent回调;如果取出的事件是Runnable任务,将在EventRunner所在线程执行Runnable的run回调。
在进行线程间通信的时候,EventHandler只能和EventRunner所创建的线程进行绑定,EventRunner创建时需要判断是否创建成功,只有确保获取的EventRunner实例非空时,才可以使用EventHandler绑定EventRunner。
一个EventHandler只能同时与一个EventRunner绑定,一个EventRunner可以同时绑定多个EventHandler。
EventRunner的工作模式可以分为托管模式和手动模式。两种模式是在调用EventRunner的create()方法时,通过选择不同的参数来实现的,默认为托管模式。
详情请参考:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/inter-thread-guidelines-0000000000038955
案例:
- 使用EventHandle发布Runnable耗时任务
1)自定义EventHandler内部类
class MyEventHander extends EventHandler {
public MyEventHander(EventRunner runner) {
super(runner);
}
@Override
protected void processEvent(InnerEvent event) {
super.processEvent(event);
if (null == event) {
return;
}
if (event instanceof InnerEvent) {
switch (event.eventId) {//根据事件id判断传递的事件类型
case 1:
//获取由InnerEvent对象的object属性封装的数据
String hello = (String) event.object;
//获取封装在InnerEvent对象中的PacMap对象
PacMap pacMap = event.getPacMap();
//获取PacMap对象中封装的键值对数据
String msg = pacMap.getString(“msg”);
//更新UI界面
txtStatus.setText(msg);
btnSend.setText(hello);
break;
case 2:
//获取线程传递的参数
int n = (int) event.param;
//更新UI界面
txtStatus.setText(n+“”);
break;
}
}
}
}
2)发布耗时任务
private void postRunnable() {
//获取EventRunner线程对象(非主线程)
EventRunner runner = EventRunner.create();
//实例化EventHandle对象
hander = new MyEventHander(runner);
//发布Runnable耗时任务
hander.postTask(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
});
System.out.println(“耗时任务执行完成”);
} - 使用EventHandle发布InnerEvent任务,并更新UI线程
1)同上
2)发布InnerEvent事件
private void sendInnerEvent() {
//获取线程对象EventRunner,current()方法表示得到当前线程(主线程)
EventRunner runner = EventRunner.current();
//实例化EventHandle对象,并绑定EventRunner线程对象
hander = new MyEventHander(runner);
//获取InnerEvent事件对象,并指定事件id
InnerEvent innerEvent = InnerEvent.get(1);
//通过事件对象的object属性封装数据
innerEvent.object = “你好吗”;
//也可以使用PacMap对象封装数据,PacMap保存键值对数据
PacMap pacMap = new PacMap();
//向PacMap对象中添加数据
pacMap.putString(“msg”, “InnerEvent + EventRunner”);
//将PacMap对象设置给InnerEvent对象
innerEvent.setPacMap(pacMap);
//传递InnerEvent事件给原线程(主线程)
hander.sendEvent(innerEvent, 0, EventHandler.Priority.LOW);
System.out.println(“发布InnerEvent+Hander”);
}
3.根据线程执行情况,频繁更新UI
1)同上
2)发布InnerEvent事件
private void sendLongTimeEvent() {
EventRunner runner = EventRunner.current();
hander = new MyEventHander(runner);
new Thread(new Runnable() {
@Override
public void run() {
for(int i = 0; i < 10; i++){
InnerEvent event = InnerEvent.get(2, (int)i);
//注意:不要使用sendEvent(2),不记录event历史记录
hander.sendEvent(event);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
原来还有这种操作,零基础的我又get了新知识
学到了!老师这个代码可以排下版就更好了
期待多多更新~