文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

HarmonyOS 基础技术赋能之公共事件(CommonEvent)开发

2024-12-02 21:39

关注

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

引言

在HarmonyOS通过CES(Common Event Service,公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力。

公共事件可分为系统公共事件和自定义公共事件。

系统公共事件:系统将收集到的事件信息,根据系统策略发送给订阅该事件的用户程序。 公共事件包括:终端设备用户可感知的亮灭屏事件,以及系统关键服务发布的系统事件(例如:USB插拔,网络连接,系统升级)等。

自定义公共事件:应用自定义一些公共事件用来处理业务逻辑。

场景介绍

每个应用都可以订阅自己感兴趣的公共事件,订阅成功后且公共事件发布后,系统会把其发送给应用。这些公共事件可能来自系统、其他应用和应用自身。HarmonyOS提供了一套完整的API,支持用户订阅、发布和接收公共事件。发布公共事件需要借助CommonEventData对象,接收公共事件需要继承CommonEventSubscriber类并实现onReceiveEvent回调函数。

开发者可以发布四种公共事件:无序的公共事件、带权限的公共事件、有序的公共事件、粘性的公共事件。

本文主讲无序的公共事件,其他类型事件,可参考华为官方开发文档学习。

指南

1.发布公共事件:

  1. try { 
  2.   Intent intent = new Intent(); 
  3.   Operation operation = new Intent.OperationBuilder() 
  4.       .withAction(“my.action”)//自定义字符串类型的action 
  5.       .build(); 
  6.   intent.setOperation(operation); 
  7.   intent.setParam("result","commonEventData"); 
  8.   intent.setParam("isCommonEvent",true); 
  9.   CommonEventData eventData = new CommonEventData(intent); 
  10.   CommonEventManager.publishCommonEvent(eventData); 
  11.   LogUtils.info(TAG,"PublishCommonEvent SUCCESS"); 
  12. } catch (RemoteException e) { 
  13.   LogUtils.error(TAG,"Exception occurred during publishCommonEvent invocation."); 

2. 订阅公共事件

1)创建CommonEventSubscriber派生类,在onReceiveEvent()回调函数中处理公共事件。

  1. private class MyCommonEventSubscriber extends CommonEventSubscriber { 
  2.     MyCommonEventSubscriber(CommonEventSubscribeInfo info) { 
  3.      super(info); 
  4.  } 
  5.  
  6.  @Override 
  7.  public void onReceiveEvent(CommonEventData commonEventData) { 

2)构造MyCommonEventSubscriber对象,调用CommonEventManager. subscribeCommonEvent()接口进行订阅。

  1. MatchingSkills matchingSkills = new MatchingSkills(); 
  2. //添加自定义的ation 
  3. matchingSkills.addEvent(ACTION);  
  4. matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_BOOT_COMPLETED); // 开机完成事件 
  5. matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_CHARGING); // 正在充电事件 
  6. CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills); 
  7. subscriber = new MyCommonEventSubscriber(subscribeInfo); 
  8. try { 
  9.   CommonEventManager.subscribeCommonEvent(subscriber); 
  10.   LogUtils.info(TAG,"SubscribeCommonEvent SUCCESS"); 
  11. } catch (RemoteException e) { 
  12.   LogUtils.error(TAG,"Exception occurred during subscribeCommonEvent invocation."); 

3)针对在onReceiveEvent中不能执行耗时操作的限制,可以使用CommonEventSubscriber的goAsyncCommonEvent()来实现异步操作,函数返回后仍保持该公共事件活跃,且执行完成后必须调用。

  1. // EventRunner创建新线程,将耗时的操作放到新的线程上执行 
  2.  private EventRunner eventRunner=EventRunner.create(); 
  3.  
  4. // MyEventHandler为EventHandler的派生类,在不同线程间分发和处理事件和Runnable任务 
  5.  private MyEventHandle myEventHandle=new MyEventHandle(eventRunner); 
  6.  
  7.  private class MyCommonEventSubscriber extends CommonEventSubscriber { 
  8.      MyCommonEventSubscriber(CommonEventSubscribeInfo info) { 
  9.       super(info); 
  10.   } 
  11.   @Override 
  12.   public void onReceiveEvent(CommonEventData commonEventData) { 
  13.         //以下为如果有耗时操作时,执行的代码 
  14.         final AsyncCommonEventResult result = goAsyncCommonEvent(); 
  15.         Runnable runnable=new Runnable() { 
  16.          @Override 
  17.          public void run() { 
  18.            // 待执行的操作,由开发者定义 
  19.            myEventHandle.sendEvent(100); 
  20.  
  21.            result.finishCommonEvent(); // 调用finish结束异步操作 
  22.          } 
  23.        }; 
  24.        myEventHandle.postTask(runnable); 
  25.   } 
  26.  
  27.  private class MyEventHandle extends EventHandler{ 
  28.  
  29.   public MyEventHandle(EventRunner runner) throws IllegalArgumentException { 
  30.     super(runner); 
  31.   } 
  32.  
  33.    @Override 
  34.    protected void processEvent(InnerEvent event) { 
  35.      super.processEvent(event); 
  36.      //处理事件,由开发者撰写 
  37.      int evnetID=event.eventId; 
  38.      LogUtils.info(TAG,"evnetID:"+evnetID); 
  39.  
  40.    } 
  41.  } 

3. 退订公共事件:

  1.  //在Ability的onStop()中调用CommonEventManager.unsubscribeCommonEvent()方法来退订公共事件。调用后,之前订阅的所有公共事件均被退订。 
  2.    @Override 
  3. protected void onStop() { 
  4.   super.onStop(); 
  5.   try { 
  6.     CommonEventManager.unsubscribeCommonEvent(subscriber); 
  7.     LogUtils.info(TAG, "unsubscribeCommonEvent success."); 
  8.   } catch (RemoteException e) { 
  9.     LogUtils.error(TAG, "Exception occurred during unsubscribeCommonEvent invocation."); 
  10.   } 

实现效果

1.启动APP时,如下图:


2. 先点击“订阅公共事件”,后点击“发布无序公共事件”。打印的log:

  1. 09-02 10:31:07.693 10390-10390/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: SubscribeCommonEvent SUCCESS 
  2. 09-02 10:31:09.795 10390-10390/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: PublishCommonEvent SUCCESS 
  3. 09-02 10:31:09.798 10390-10390/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: action:action.send.message/result:commonEventData/isCommonEvent:true 
  4. 09-02 10:31:09.799 10390-12455/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: evnetID:100    

附上源码

1.MainAbilitySlice

  1. public class MainAbilitySlice extends AbilitySlice implements ClickedListener { 
  2.   private String TAG="MainAbilitySlice"
  3.   private MyCommonEventSubscriber subscriber; 
  4.   private static final String ACTION="action.send.message"
  5.  
  6.   @Override 
  7.   public void onStart(Intent intent) { 
  8.     super.onStart(intent); 
  9.     super.setUIContent(ResourceTable.Layout_ability_main); 
  10.     Button btPublisher=(Button)findComponentById(ResourceTable.Id_btPublisher); 
  11.     Button btSubscriber=(Button)findComponentById(ResourceTable.Id_btSubscriber); 
  12.     btPublisher.setClickedListener(this); 
  13.     btSubscriber.setClickedListener(this); 
  14.   } 
  15.  
  16.   @Override 
  17.   public void onActive() { 
  18.     super.onActive(); 
  19.   } 
  20.  
  21.   @Override 
  22.   public void onForeground(Intent intent) { 
  23.     super.onForeground(intent); 
  24.   } 
  25.  
  26.   @Override 
  27.   public void onClick(Component component) { 
  28.     switch (component.getId()){ 
  29.       case ResourceTable.Id_btPublisher: 
  30.         try { 
  31.           Intent intent = new Intent(); 
  32.           Operation operation = new Intent.OperationBuilder() 
  33.               .withAction(ACTION
  34.               .build(); 
  35.           intent.setOperation(operation); 
  36.           intent.setParam("result","commonEventData"); 
  37.           intent.setParam("isCommonEvent",true); 
  38.           CommonEventData eventData = new CommonEventData(intent); 
  39.           CommonEventManager.publishCommonEvent(eventData); 
  40.           LogUtils.info(TAG,"PublishCommonEvent SUCCESS"); 
  41.         } catch (RemoteException e) { 
  42.           LogUtils.error(TAG,"Exception occurred during publishCommonEvent invocation."); 
  43.         } 
  44.         break; 
  45.       case ResourceTable.Id_btSubscriber: 
  46.         MatchingSkills matchingSkills = new MatchingSkills(); 
  47.         //添加自定义的ation 
  48.         matchingSkills.addEvent(ACTION);//自定义事件 
  49.         matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_BOOT_COMPLETED); // 开机完成事件 
  50.         matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_CHARGING); // 正在充电事件 
  51.         CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills); 
  52.         subscriber = new MyCommonEventSubscriber(subscribeInfo); 
  53.         try { 
  54.           CommonEventManager.subscribeCommonEvent(subscriber); 
  55.           LogUtils.info(TAG,"SubscribeCommonEvent SUCCESS"); 
  56.         } catch (RemoteException e) { 
  57.           LogUtils.error(TAG,"Exception occurred during subscribeCommonEvent invocation."); 
  58.         } 
  59.         break; 
  60.     } 
  61.  
  62.   } 
  63.    //// EventRunner创建新线程,将耗时的操作放到新的线程上执行 
  64.    private EventRunner eventRunner=EventRunner.create(); 
  65.  
  66.   // MyEventHandler为EventHandler的派生类,在不同线程间分发和处理事件和Runnable任务 
  67.    private MyEventHandle myEventHandle=new MyEventHandle(eventRunner); 
  68.  
  69.    private class MyCommonEventSubscriber extends CommonEventSubscriber { 
  70.        MyCommonEventSubscriber(CommonEventSubscribeInfo info) { 
  71.         super(info); 
  72.     } 
  73.  
  74.       
  75.     @Override 
  76.     public void onReceiveEvent(CommonEventData commonEventData) { 
  77.           //非执行耗时操作,以下代码即可 
  78.           Intent intent=commonEventData.getIntent(); 
  79.           String action= intent.getAction(); 
  80.           switch (action){ 
  81.             //自定义事件 
  82.             case ACTION
  83.               String result=intent.getStringParam("result"); 
  84.               boolean isCommonEventData=intent.getBooleanParam("isCommonEvent",false); 
  85.               LogUtils.info(TAG,"action:"+action+"/result:"+result+"/isCommonEvent:"+isCommonEventData); 
  86.               break; 
  87.             // 开机完成事件 
  88.             case CommonEventSupport.COMMON_EVENT_BOOT_COMPLETED: 
  89.               LogUtils.info(TAG,"action:"+action); 
  90.               break; 
  91.             // 正在充电事件 
  92.             case CommonEventSupport.COMMON_EVENT_CHARGING: 
  93.               LogUtils.info(TAG,"action:"+action); 
  94.               break; 
  95.           } 
  96.  
  97.  
  98.           //以下为如果有耗时操作时,选择执行的代码 
  99.           final AsyncCommonEventResult result = goAsyncCommonEvent(); 
  100.           Runnable runnable=new Runnable() { 
  101.            @Override 
  102.            public void run() { 
  103.              // 待执行的操作,由开发者定义 
  104.              myEventHandle.sendEvent(100); 
  105.  
  106.  
  107.              result.finishCommonEvent(); // 调用finish结束异步操作 
  108.            } 
  109.          }; 
  110.          myEventHandle.postTask(runnable); 
  111.     } 
  112.   } 
  113.  
  114.    private class MyEventHandle extends EventHandler{ 
  115.  
  116.     public MyEventHandle(EventRunner runner) throws IllegalArgumentException { 
  117.       super(runner); 
  118.     } 
  119.  
  120.      @Override 
  121.      protected void processEvent(InnerEvent event) { 
  122.        super.processEvent(event); 
  123.        //处理事件,由开发者撰写 
  124.        int evnetID=event.eventId; 
  125.        LogUtils.info(TAG,"evnetID:"+evnetID); 
  126.  
  127.      } 
  128.    } 
  129.  
  130.  
  131.   @Override 
  132.   protected void onStop() { 
  133.     super.onStop(); 
  134.     try { 
  135.       CommonEventManager.unsubscribeCommonEvent(subscriber); 
  136.       LogUtils.info(TAG, "unsubscribeCommonEvent success."); 
  137.     } catch (RemoteException e) { 
  138.       LogUtils.error(TAG, "Exception occurred during unsubscribeCommonEvent invocation."); 
  139.     } 
  140.   } 

2.LogUtils

  1. public class LogUtils { 
  2.     private static final String TAG_LOG = "LogUtil"
  3.  
  4.     private static final HiLogLabel LABEL_LOG = new HiLogLabel(0, 0, LogUtils.TAG_LOG); 
  5.  
  6.     private static final String LOG_FORMAT = "%{public}s: %{public}s"
  7.  
  8.     private LogUtils() { } 
  9.  
  10.      
  11.     public static void debug(String tag, String msg) { 
  12.         HiLog.debug(LABEL_LOG, LOG_FORMAT, tag, msg); 
  13.     } 
  14.  
  15.      
  16.     public static void info(String tag, String msg) { 
  17.         HiLog.info(LABEL_LOG, LOG_FORMAT, tag, msg); 
  18.     } 
  19.  
  20.      
  21.     public static void warn(String tag, String msg) { 
  22.         HiLog.warn(LABEL_LOG, LOG_FORMAT, tag, msg); 
  23.     } 
  24.  
  25.      
  26.     public static void error(String tag, String msg) { 
  27.         HiLog.error(LABEL_LOG, LOG_FORMAT, tag, msg); 
  28.     } 

3. xml 布局文件:

  1. "1.0" encoding="utf-8"?> 
  2.   xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  3.   ohos:height="match_parent" 
  4.   ohos:orientation="vertical" 
  5.   ohos:width="match_parent"
  6.  
  7.  
  8.   
  9.     ohos:height="match_content" 
  10.     ohos:width="match_parent" 
  11.     ohos:left_margin="20vp" 
  12.     ohos:right_margin="20vp" 
  13.     ohos:top_margin="50vp" 
  14.     ohos:orientation="vertical"
  15.     
  16.       ohos:id="$+id:btPublisher" 
  17.       ohos:height="match_content" 
  18.       ohos:width="match_content" 
  19.       ohos:text_size="22vp" 
  20.       ohos:text_color="#ffffff" 
  21.       ohos:text="发布无序公共事件" 
  22.       ohos:padding="20vp" 
  23.       ohos:background_element="#00ffff"/> 
  24.  
  25.     
  26.       ohos:id="$+id:btSubscriber" 
  27.       ohos:height="match_content" 
  28.       ohos:width="match_content" 
  29.       ohos:text_size="22vp" 
  30.       ohos:text_color="#ffffff" 
  31.       ohos:text="订阅公共事件" 
  32.       ohos:padding="20vp" 
  33.       ohos:top_margin="30vp" 
  34.       ohos:background_element="#00ffff"/> 
  35.    
  36.  
  37.  

 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯