鸿蒙OS线程间的通讯EventHandler详解

鸿蒙线程通讯EventHandler介绍

鸿蒙OS系统开发:环境搭建详解和运行Hello World

在开发过程中,开发者经常需要在当前线程中处理下载任务等较为耗时的操作,但是又不希望当前的线程受到阻塞。此时,就可以使用EventHandler机制。EventHandler是HarmonyOS用于处理线程间通信的一种机制,可以通过EventRunner创建新线程,将耗时的操作放到新线程上执行。这样既不阻塞原来的线程,任务又可以得到合理的处理。比如:主线程使用EventHandler创建子线程,子线程做耗时的下载图片操作,下载完成后,子线程通过EventHandler通知主线程,主线程再更新UI。

基本概念

EventRunner是一种事件循环器,循环处理从该EventRunner创建的新线程的事件队列中获取InnerEvent事件或者Runnable任务。InnerEvent是EventHandler投递的事件。

EventHandler是一种用户在当前线程上投递InnerEvent事件或者Runnable任务到异步线程上处理的机制。每一个EventHandler和指定的EventRunner所创建的新线程绑定,并且该新线程内部有一个事件队列。EventHandler可以投递指定的InnerEvent事件或Runnable任务到这个事件队列。EventRunner从事件队列里循环地取出事件,如果取出的事件是InnerEvent事件,将在EventRunner所在线程执行processEvent回调;如果取出的事件是Runnable任务,将在EventRunner所在线程执行Runnable的run回调。一般,EventHandler有两个主要作用:

  • 在不同线程间分发和处理InnerEvent事件或Runnable任务。
  • 延迟处理InnerEvent事件或Runnable任务。

运作机制

EventHandler的运作机制如下图所示:

图片

使用EventHandler实现线程间通信的主要流程:

  1. EventHandler投递具体的InnerEvent事件或者Runnable任务到EventRunner所创建的线程的事件队列。
  2. EventRunner循环从事件队列中获取InnerEvent事件或者Runnable任务。
  3. 处理事件或任务:
    • 如果EventRunner取出的事件为InnerEvent事件,则触发EventHandler的回调方法并触发EventHandler的处理方法,在新线程上处理该事件。
    • 如果EventRunner取出的事件为Runnable任务,则EventRunner直接在新线程上处理Runnable任务。

约束限制

  • 在进行线程间通信的时候,EventHandler只能和EventRunner所创建的线程进行绑定,EventRunner创建时需要判断是否创建成功,只有确保获取的EventRunner实例非空时,才可以使用EventHandler绑定EventRunner。
  • 一个EventHandler只能同时与一个EventRunner绑定,一个EventRunner可以同时绑定多个EventHandler。

应用例子:

EventHandler从新创建的线程投递事件到原线程并进行处理,开发步骤如下:


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 runner = EventRunner.create(false);// create()的参数是true时,则为托管模式。
MyEventHandler myHandler = new MyEventHandler(runner);
long param = 0L; 
InnerEvent event = InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD, param, EventRunner.current());
// 将与当前线程绑定的EventRunner投递到与runner创建的新线程中
myHandler.sendEvent(event);
阅读原文

简介:一个有10多年经验开发的android、java、前端等语言的老程序员,在这里一起聊聊技术,一起聊聊生活、一起聊聊中年危机的生存之道,一起进步一起加油,感兴趣的欢迎订阅;不定时的更新。欢迎关注微信公众号:Android开发编程
(0)
打赏 喜欢就点个赞支持下吧 喜欢就点个赞支持下吧

声明:本文来自“Android开发编程”,分享链接:https://www.zyxiao.com/p/290356    侵权投诉

网站客服
网站客服
内容投稿 侵权处理
分享本页
返回顶部