当前位置: 首页 > 科技观察

HarmonyOSSample的EventHandler线程间通信

时间:2023-03-23 11:46:05 科技观察

更多内容请访问:Harmonyos技术社区https://harmonyos.51cto.com1.简介在开发过程中,开发者经常需要进行下载任务等耗时操作在当前线程中处理,但当前线程预计不会被阻塞。此时,就可以使用EventHandler机制了。EventHandler是HarmonyOS用来处理线程间通信的一种机制。通过EventRunner可以创建一个新线程,在新线程上执行耗时操作。这样就不会阻塞原来的线程,可以合理的处理任务。例如:主线程使用EventHandler创建子线程,子线程做耗时的图片下载操作。下载完成后,子线程通过EventHandler通知主线程,主线程更新UI。2.搭建环境,安装DevEcoStudio。具体请参考DevEcoStudio下载。搭建DevEcoStudio开发环境。DevEcoStudio开发环境依赖于网络环境。需要联网才能保证工具的正常使用。开发环境可根据以下两种情况进行配置:如果可以直接上网,只需要下载HarmonyOSSDK即可运行。如果网络不能直接访问Internet,则需要通过代理服务器访问。请参考配置开发环境。下载源码后,使用DevEcoStudio打开项目。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.1InitializeEventRunner,EventHandlerobject/***initializeobject*/privatevoidinitHandler(){//创建一个eventrunner,默认是managed模式,create()的参数为false时,是manual模式eventRunner=EventRunner.create("TestRunner");//初始化eventhandler,需要传入一个eventrunnerhandler=newTestEventHandler(eventRunner);//第二个EventHandlermyHandler=newMyEventHandler(eventRunner);}4.2.2发送普通event/***发送一个普通事件*@paramcomponent*/privatevoidsendInnerEvent(Componentcomponent){stringBuffer=newStringBuffer();longparam=0L;//获取一个事件结构对象//InnerEvent对象包含一个额外的整型字段和一个附加对象携带特定数据的字段。InnerEventnormalInnerEvent=InnerEvent.get(EVENT_MESSAGE_NORMAL,param,null);InnerEventdelayInnerEvent=InnerEvent.get(EVENT_MESSAGE_DELAY,param,null);//发送事件,事件结构对象+事件级别//IMMEDIATE:即时;IDLE:闲置;HIGH:high;LOW:Lowhandler.sendEvent(normalInnerEvent,EventHandler.Priority.IMMEDIATE);HiLog.debug(LABEL,"SendaNormalEventdone");//发送一个延时事件,事件结构对象+延时时间+事件级别handler.sendEvent(delayInnerEvent,DELAY_TIME,EventHandler.Priority.IMMEDIATE);HiLog.debug(LABEL,"SendaDelayEventdone");}输出结果09-0912:14:36.51214769-14769/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:SendaNormalEventdone42:451941914209:-14769/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:SendaDelayEventdone09-0912:14:36.51214769-15211/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:ReceivedaNormalEvent163116087651209-0912:14:37.51214769-15211/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:ReceivedaDelayEvent16311608775124.2.3发布可运行任务/***发布可运行任务*@paramcomponent*/privatevoidpostRunnableTask(Componentcomponent){stringBuffer=newStringBuffer();//Task1//Runnable任务会在EventRunner所在线程执行Runnable的run回调Runnabletask1=()->{stringBuffer.append("PostrunnableTask1done").append(System.lineSeparator());getUITaskDispatcher().asyncDispatch(()->resultText.setText(stringBuffer.toString()));HiLog.debug(LABEL,"PostrunnableTask1doneasyncDispatch");};//Task2//可运行任务,会在EventRunner所在的线程中执行Runnable的运行回调。Runnabletask2=()->{stringBuffer.append("PostrunnableTask2done").append(System.lineSeparator());getUITaskDispatcher().asyncDispatch(()->resultText.setText(stringBuffer.toString()));HiLog.debug(LABEL,"PostrunnableTask2doneasyncDispatch");};HiLog.debug(LABEL,"MainTaskrun1...");//发布任务myHandler.postTask(task1,EventHandler.Priority.IMMEDIATE);HiLog.debug(LABEL,"MainTaskrun2..");//发布延迟任务,所以在task1后执行myHandler.postTask(task2,DELAY_TIME,EventHandler.Priority.IMMEDIATE);HiLog.debug(LABEL,"MainTaskrun3...");}输出结果09-0910:21:43.67219863-19863/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:MainTaskrun1...09-0910:21:43.67219863-19863/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:MainTaskrun2...0921:43.67219863-19863/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:MainTaskrun3...09-0910:21:43.67319863-31145/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:PostrunnableTask1doneasyDispatch09-0910:21:44.67519863-31145/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:PostrunnableTask2doneasyncDispatch4.2.4发送跨线程事件/***发送跨线程事件*@paramcomponent*/privatevoidsendToOriginalThread(componingalThread)newStringBuffer();longparam=0;//获取一个跨线程事件结构对象InnerEventinnerEvent=InnerEvent.get(EVENT_MESSAGE_CROSS_THREAD,param,eventRunner);//发送一个延迟事件handler.sendEvent(innerEvent,DELAY_TIME,EventHandler.Priority.IMMEDIATE);/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:ReceivedaCrossThreadAndDelayEvent163116092962609-0912:15:29.62614769-15211/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:sendaReplyEvent163116092962609-0912:15:29.62614769-15211/ohos.samples.eventhandlerD00001/=>MainAbilitySlice:receiveaReplyEvent16311609296264.2.5继承事件处理类,重写处理事件的方法/***继承事件处理类,重写处理事件的方法*/privateclassTestEventHandlerextendsEventHandler{/***默认构造函数*@paramrunner*/privateTestEventHandler(EventRunnerrunner){super(runner);}@OverridepublicvoidprocessEvent(InnerEventevent){switch(event.eventId){caseEVENT_MESSAGE_NORMAL:HiLog.debug(LABEL,"ReceivedaNormalEvent"+System.currentTimeMillis());stringBufferappend("ReceivedaninnerEventmessage").append(System.lineSeparator());getUITaskDispatcher().asyncDispatch(()->resultText.setText(stringBuffer.toString()));break;caseEVENT_MESSAGE_DELAY:HiLog.debug(LABEL,"ReceivedaDelayEvent"+System.currentTimeMillis());stringBuffer.append("ReceivedaninnerEventdelaymessage").append(System.lineSeparator());getUITaskDispatcher().asyncDispatch(()->resultText.setText(stringBuffer.toString()));中断;案例EVENT_MESSAGE_CROSS_THREAD:HiLog.debug(标签,"ReceivedaCrossThreadAndDelayEvent"+System.currentTimeMillis());//接收事件对象Objectobject=event.object;//判断对象类型if(objectinstanceofEventRunner){//将原线程的EventRunner实例传给新创建的线程EventRunnerrunner=(EventRunner)object;//将原线程的EventRunner实例与新创建线程的EventHandler绑定threadHiLog.debug(LABEL,"receiveaReplyEvent"+System.currentTimeMillis());stringBuffer.append("OriginalThreadreceiveamessage");getUITaskDispatcher().asyncDispatch(()->resultText.setText(stringBuffer.toString()));}};inttestEventId=1;longtestParam=0;//获取事件传递的参数InnerEventinnerEvent=InnerEvent.get(testEventId,testParam,null);///将事件发送到原线程eventHandler.sendEvent(innerEvent);HiLog.调试(标签,“sendaReplyEvent”+系统。currentTimeMillis());}break;default:break;}}}五、问题与思考5.1发布定时任务到队列没有得到预期的效果//TODO没有得到预期的效果myHandler.postTimingTask(task1,System.currentTimeMillis()+1000L,EventHandler.Priority.IMMEDIATE);5.2想想例子中哪里体现了“oneEventRunnercanbindmultipleEventHandlersatthesametime”这句话?6.完整代码附件直接下载。更多信息请访问:Harmonyos技术社区https://harmonyos.51cto.com与华为官方共建

最新推荐
猜你喜欢