
想了解更多内容,础技请访问:
和华为官方合作共建的术赋事件鸿蒙技术社区
https://harmonyos.51cto.com
引言
在HarmonyOS通过CES(Common Event Service,公共事件服务)为应用程序提供订阅、公共发布、础技退订公共事件的术赋事件能力。
公共事件可分为系统公共事件和自定义公共事件。公共
系统公共事件:系统将收集到的础技事件信息,根据系统策略发送给订阅该事件的术赋事件用户程序。 公共事件包括:终端设备用户可感知的公共亮灭屏事件,以及系统关键服务发布的础技系统事件(例如:USB插拔,网络连接,术赋事件系统升级)等。公共
自定义公共事件:应用自定义一些公共事件用来处理业务逻辑。础技
场景介绍
每个应用都可以订阅自己感兴趣的术赋事件公共事件,订阅成功后且公共事件发布后,公共系统会把其发送给应用。这些公共事件可能来自系统、其他应用和应用自身。HarmonyOS提供了一套完整的API,支持用户订阅、发布和接收公共事件。发布公共事件需要借助CommonEventData对象,接收公共事件需要继承CommonEventSubscriber类并实现onReceiveEvent回调函数。
开发者可以发布四种公共事件:无序的b2b供应网公共事件、带权限的公共事件、有序的公共事件、粘性的公共事件。
本文主讲无序的公共事件,其他类型事件,可参考华为官方开发文档学习。
指南
1.发布公共事件:
try {   Intent intent = new Intent();   Operation operation = new Intent.OperationBuilder()       .withAction(“my.action”)//自定义字符串类型的action       .build();   intent.setOperation(operation);   intent.setParam("result","commonEventData");   intent.setParam("isCommonEvent",true);   CommonEventData eventData = new CommonEventData(intent);   CommonEventManager.publishCommonEvent(eventData);   LogUtils.info(TAG,"PublishCommonEvent SUCCESS"); } catch (RemoteException e) {   LogUtils.error(TAG,"Exception occurred during publishCommonEvent invocation."); }         
2. 订阅公共事件
1)创建CommonEventSubscriber派生类,在onReceiveEvent()回调函数中处理公共事件。
private class MyCommonEventSubscriber extends CommonEventSubscriber {     MyCommonEventSubscriber(CommonEventSubscribeInfo info) {      super(info);  }  @Override  public void onReceiveEvent(CommonEventData commonEventData) { }         
2)构造MyCommonEventSubscriber对象,调用CommonEventManager. subscribeCommonEvent()接口进行订阅。
MatchingSkills matchingSkills = new MatchingSkills(); //添加自定义的ation matchingSkills.addEvent(ACTION);  matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_BOOT_COMPLETED); // 开机完成事件 matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_CHARGING); // 正在充电事件 CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills); subscriber = new MyCommonEventSubscriber(subscribeInfo); try {   CommonEventManager.subscribeCommonEvent(subscriber);   LogUtils.info(TAG,"SubscribeCommonEvent SUCCESS"); } catch (RemoteException e) {   LogUtils.error(TAG,"Exception occurred during subscribeCommonEvent invocation."); }         
3)针对在onReceiveEvent中不能执行耗时操作的限制,可以使用CommonEventSubscriber的goAsyncCommonEvent()来实现异步操作,函数返回后仍保持该公共事件活跃,且执行完成后必须调用。
// EventRunner创建新线程,将耗时的操作放到新的线程上执行  private EventRunner eventRunner=EventRunner.create(); // MyEventHandler为EventHandler的派生类,在不同线程间分发和处理事件和Runnable任务  private MyEventHandle myEventHandle=new MyEventHandle(eventRunner);  private class MyCommonEventSubscriber extends CommonEventSubscriber {      MyCommonEventSubscriber(CommonEventSubscribeInfo info) {       super(info);   }   @Override   public void onReceiveEvent(CommonEventData commonEventData) {         //以下为如果有耗时操作时,执行的代码         final AsyncCommonEventResult result = goAsyncCommonEvent();         Runnable runnable=new Runnable() {          @Override          public void run() {            // 待执行的
源码下载操作,由开发者定义            myEventHandle.sendEvent(100);            result.finishCommonEvent(); // 调用finish结束异步操作          }        };        myEventHandle.postTask(runnable);   } }  private class MyEventHandle extends EventHandler{   public MyEventHandle(EventRunner runner) throws IllegalArgumentException {     super(runner);   }    @Override    protected void processEvent(InnerEvent event) {      super.processEvent(event);      //处理事件,由开发者撰写      int evnetID=event.eventId;      LogUtils.info(TAG,"evnetID:"+evnetID);    }  }         
3. 退订公共事件:
 //在Ability的onStop()中调用CommonEventManager.unsubscribeCommonEvent()方法来退订公共事件。调用后,之前订阅的所有公共事件均被退订。    @Override protected void onStop() {   super.onStop();   try {     CommonEventManager.unsubscribeCommonEvent(subscriber);     LogUtils.info(TAG, "unsubscribeCommonEvent success.");   } catch (RemoteException e) {     LogUtils.error(TAG, "Exception occurred during unsubscribeCommonEvent invocation.");   } }         
实现效果
1.启动APP时,如下图:

2. 先点击“订阅公共事件”,后点击“发布无序公共事件”。打印的log:
09-02 10:31:07.693 10390-10390/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: SubscribeCommonEvent SUCCESS 09-02 10:31:09.795 10390-10390/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: PublishCommonEvent SUCCESS 09-02 10:31:09.798 10390-10390/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: action:action.send.message/result:commonEventData/isCommonEvent:true 09-02 10:31:09.799 10390-12455/com.zel.commoneventdemo I 00000/LogUtil: MainAbilitySlice: evnetID:100            
附上源码
1.MainAbilitySlice
public class MainAbilitySlice extends AbilitySlice implements ClickedListener {   private String TAG="MainAbilitySlice";   private MyCommonEventSubscriber subscriber;   private static final String ACTION="action.send.message";   @Override   public void onStart(Intent intent) {     super.onStart(intent);     super.setUIContent(ResourceTable.Layout_ability_main);     Button btPublisher=(Button)findComponentById(ResourceTable.Id_btPublisher);     Button btSubscriber=(Button)findComponentById(ResourceTable.Id_btSubscriber);     btPublisher.setClickedListener(this);     btSubscriber.setClickedListener(this);   }   @Override   public void onActive() {     super.onActive();   }   @Override   public void onForeground(Intent intent) {     super.onForeground(intent);   }   @Override   public void onClick(Component component) {     switch (component.getId()){       case ResourceTable.Id_btPublisher:         try {           Intent intent = new Intent();           Operation operation = new Intent.OperationBuilder()               .withAction(ACTION)               .build();           intent.setOperation(operation);           intent.setParam("result","commonEventData");           intent.setParam("isCommonEvent",true);           CommonEventData eventData = new CommonEventData(intent);           CommonEventManager.publishCommonEvent(eventData);           LogUtils.info(TAG,"PublishCommonEvent SUCCESS");         } catch (RemoteException e) {           LogUtils.error(TAG,"Exception occurred during publishCommonEvent invocation.");         }         break;       case ResourceTable.Id_btSubscriber:         MatchingSkills matchingSkills = new MatchingSkills();         //添加自定义的ation         matchingSkills.addEvent(ACTION);//自定义事件         matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_BOOT_COMPLETED); // 开机完成事件         matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_CHARGING); // 正在充电事件         CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);         subscriber = new MyCommonEventSubscriber(subscribeInfo);         try {           CommonEventManager.subscribeCommonEvent(subscriber);           LogUtils.info(TAG,"SubscribeCommonEvent SUCCESS");         } catch (RemoteException e) {           LogUtils.error(TAG,"Exception occurred during subscribeCommonEvent invocation.");         }         break;     }   }    //// EventRunner创建新线程,将耗时的操作放到新的线程上执行    private EventRunner eventRunner=EventRunner.create();   // MyEventHandler为EventHandler的派生类,在不同线程间分发和处理事件和Runnable任务    private MyEventHandle myEventHandle=new MyEventHandle(eventRunner);    private class MyCommonEventSubscriber extends CommonEventSubscriber {        MyCommonEventSubscriber(CommonEventSubscribeInfo info) {         super(info);     }      /**       * 针对在onReceiveEvent中不能执行耗时操作的限制,可以使用CommonEventSubscriber的goAsyncCommonEvent()来实现异步操作,       * 函数返回后仍保持该公共事件活跃,且执行完成后必须调用AsyncCommonEventResult.finishCommonEvent()来结束。       * @param commonEventData       */     @Override     public void onReceiveEvent(CommonEventData commonEventData) {           //非执行耗时操作,以下代码即可           Intent intent=commonEventData.getIntent();           String action= intent.getAction();           switch (action){             //自定义事件             case ACTION:               String result=intent.getStringParam("result");               boolean isCommonEventData=intent.getBooleanParam("isCommonEvent",false);               LogUtils.info(TAG,"action:"+action+"/result:"+result+"/isCommonEvent:"+isCommonEventData);               break;             // 开机完成事件             case CommonEventSupport.COMMON_EVENT_BOOT_COMPLETED:               LogUtils.info(TAG,"action:"+action);               break;             // 正在充电事件             case CommonEventSupport.COMMON_EVENT_CHARGING:               LogUtils.info(TAG,"action:"+action);               break;           }           //以下为如果有耗时操作时,选择执行的代码           final AsyncCommonEventResult result = goAsyncCommonEvent();           Runnable runnable=new Runnable() {            @Override            public void run() {              // 待执行的操作,由开发者定义              myEventHandle.sendEvent(100);              result.finishCommonEvent(); // 调用finish结束异步操作            }          };          myEventHandle.postTask(runnable);     }   }    private class MyEventHandle extends EventHandler{     public MyEventHandle(EventRunner runner) throws IllegalArgumentException {       super(runner);     }      @Override      protected void processEvent(InnerEvent event) {        super.processEvent(event);        //处理事件,由开发者撰写        int evnetID=event.eventId;        LogUtils.info(TAG,"evnetID:"+evnetID);      }    }   @Override   protected void onStop() {     super.onStop();     try {       CommonEventManager.unsubscribeCommonEvent(subscriber);       LogUtils.info(TAG, "unsubscribeCommonEvent success.");     } catch (RemoteException e) {       LogUtils.error(TAG, "Exception occurred during unsubscribeCommonEvent invocation.");     }   } }         
2.LogUtils
public class LogUtils {     private static final String TAG_LOG = "LogUtil";     private static final HiLogLabel LABEL_LOG = new HiLogLabel(0, 0, LogUtils.TAG_LOG);     private static final String LOG_FORMAT = "%{public}s: %{public}s";     private LogUtils() { }     /**      * Print debug log      *      * @param tag log tag      * @param msg log message      */     public static void debug(String tag, String msg) {         HiLog.debug(LABEL_LOG, LOG_FORMAT, tag, msg);     }     /**      * Print info log      *      * @param tag log tag      * @param msg log message      */     public static void info(String tag, String msg) {         HiLog.info(LABEL_LOG, LOG_FORMAT, tag, msg);     }     /**      * Print warn log      *      * @param tag log tag      * @param msg log message      */     public static void warn(String tag, String msg) {         HiLog.warn(LABEL_LOG, LOG_FORMAT, tag, msg);     }     /**      * Print error log      *      * @param tag log tag      * @param msg log message      */     public static void error(String tag, String msg) {         HiLog.error(LABEL_LOG, LOG_FORMAT, tag, msg);     } }         
3. xml 布局文件:
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout   xmlns:ohos="http://schemas.huawei.com/res/ohos"   ohos:height="match_parent"   ohos:orientation="vertical"   ohos:width="match_parent">     <DirectionalLayout     ohos:height="match_content"     ohos:width="match_parent"     ohos:left_margin="20vp"     ohos:right_margin="20vp"     ohos:top_margin="50vp"     ohos:orientation="vertical">     <Button       ohos:id="$+id:btPublisher"       ohos:height="match_content"       ohos:width="match_content"       ohos:text_size="22vp"       ohos:text_color="#ffffff"       ohos:text="发布无序公共事件"       ohos:padding="20vp"       ohos:background_element="#00ffff"/>      <Button       ohos:id="$+id:btSubscriber"       ohos:height="match_content"       ohos:width="match_content"       ohos:text_size="22vp"       ohos:text_color="#ffffff"       ohos:text="订阅公共事件"       ohos:padding="20vp"       ohos:top_margin="30vp"       ohos:background_element="#00ffff"/>   </DirectionalLayout>  </DirectionalLayout>         
想了解更多内容,请访问:
和华为官方合作共建的云服务器提供商鸿蒙技术社区
https://harmonyos.51cto.com

-->