# 11.1:公共事件

OpenHarmony 提供了许多系统事件,比如屏幕息屏亮屏事件、USB插拔事件以及APP的安装卸载等,由于这些事件是系统发出的,如果需要监听这些系统事件,比如设备电量低需要给用户提示充电等场景该怎么办喃?ArkUI开发框架给我们提供了 @ohos.commonEvent 模块,它不仅可以订阅系统事件,而且还可以订阅和发布自定义事件,本节笔者简单介绍一下该库相关 API 的使用。

# 11.1.1:commonEvent定义介绍

declare namespace commonEvent {
  function publish(event: string, callback: AsyncCallback<void>): void;
  function publish(event: string, options: CommonEventPublishData, callback: AsyncCallback<void>): void;
  function publishAsUser(event: string, userId: number, callback: AsyncCallback<void>): void;
  function publishAsUser(event: string, userId: number, options: CommonEventPublishData, callback: AsyncCallback<void>): void;
  function createSubscriber(subscribeInfo: CommonEventSubscribeInfo, callback: AsyncCallback<CommonEventSubscriber>): void;
  function createSubscriber(subscribeInfo: CommonEventSubscribeInfo): Promise<CommonEventSubscriber>;
  function subscribe(subscriber: CommonEventSubscriber, callback: AsyncCallback<CommonEventData>): void;
  function unsubscribe(subscriber: CommonEventSubscriber, callback?: AsyncCallback<void>): void;
}
1
2
3
4
5
6
7
8
9
10
  • publish:发送公共事件,event 表示事件名称。
  • publishAsUser:发送指定用户的公共事件。
  • createSubscriber:创建事件的订阅者。
  • subscribe:订阅事件,可以是公共事件,也可以是自定义事件。
  • unsubscribe:取消订阅事件,一旦取消,后续对的事件将不再接收。

@ohos.commonEvent 模块提供的 API 使用很简单,首先创建接收事件的订阅者,然后开始订阅事件,最后取消订阅。发布事件直接调用 publish() 方法发布事件即可,如果事件匹配到订阅者订阅的事件类型,就会回调给订阅者,简单步骤如下所示:

# 11.1.2:commonEvent订阅事件

  1. 引入commonEvent模块

    import commonEvent from '@ohos.commonEvent';
    
    1
  2. 创建订阅者

    commonEvent.createSubscriber({
      events: ["testEvent"]// 接收的指定事件名称,可以为多个事件
    }, (err, subscriber) => {
      if(err) {
        // 订阅异常的逻辑处理
      } else {
        // subscriber供后续订阅做准备
      }
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  3. 开启事件订阅

    commonEvent.createSubscriber({
      events: ["testEvent"]
    }, (err, subscriber) => {
      if(err) {
        // 异常处理
      } else {
        // 通过创建的subscriber开启事件订阅
        commonEvent.subscribe(subscriber, (err, data) => {
          if(err) {
            // 错误逻辑处理
          } else {
            // 接收到事件,开始处理
          }
        })
      }
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

# 11.1.3:commonEvent发布事件

@ohos.commonEvent 模块提供了两个方法发布事件,一个是不带参数的事件,另一个是可以带有额外参数的事件,如下所示:

  1. 发布无参数事件

    commonEvent.publish("testEvent", (err) => {// testEvent表示发布的事件名称
      if(err) {
        // 事件发布失败
      } else {
        // 事件发布成功
      }
    })
    
    1
    2
    3
    4
    5
    6
    7
  2. 发布有参数事件

    commonEvent.publish("testEvent", {// testEvent表示发布的事件名称
      code: 10086,
      data: "publish with data"
    }, (err) => {
      if(err) {
        this.publish = "publish event error: " + err.code + ", " + err.message + ", " + err.name + ", " + err.stack;
      } else {
        this.publish = "publish event success";
      }
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

以上就是事件的订阅和发布用法,接下来我们举一个简单示例演示一下:

import commonEvent from '@ohos.commonEvent';    // 引入事件包

@Entry @Component struct Index {

  @State text: string = "";
  @State publish: string = "";

  private subscriber = null;

  private createSubscriber() {
    if (this.subscriber) {
      this.text = "subscriber already created";
    } else {
      commonEvent.createSubscriber({            // 创建订阅者
        events: ["testEvent"]                   // 指定订阅的事件名称
      }, (err, subscriber) => {                 // 创建结果的回调
        if(err) {
          this.text = "create subscriber failure"
        } else {
          this.subscriber = subscriber;         // 创建订阅成功
          this.text = "create subscriber success";
        }
      })
    }
  }

  private subscribe() {
    if (this.subscriber) {
      // 根据创建的subscriber开始订阅事件
      commonEvent.subscribe(this.subscriber, (err, data) => {
        if(err) {
          // 异常处理
          this.text = "subscribe event failure: " + err;
        } else {
          // 接收到事件
          this.text = "subscribe event success: " + data.event + ", " + data;
        }
      })
    } else {
      this.text = "please create subscriber";
    }
  }

  private unsubscribe() {
    if (this.subscriber) {
      commonEvent.unsubscribe(this.subscriber, (err) => {// 取消订阅事件
        if(err) {
          this.text = "unsubscribe event failure: " + err;
        } else {
          this.subscriber = null;
          this.text = "unsubscribe event success: ";
        }
      })
    } else {
      this.text = "already subscribed";
    }
  }

  private publishEvent() {
    commonEvent.publish("testEvent", (err) => {// 发布事件,事件名称为testEvent
      if(err) {// 结果回调
        this.publish = "publish event error: " + err.code + ", " + err.message + ", " + err.name + ", " + err.stack;
      } else {
        this.publish = "publish event success";
      }
    })
  }

  private publishEventWithData() {
    commonEvent.publish("testEvent", {         // 发布事件,事件名称为testEvent
      code: 10086,                             // 事件携带的参数
      data: "publish with data"                // 事件携带的参数
    }, (err) => {                              // 结果回调
      if(err) {
        this.publish = "publish event error: " + err.code + ", " + err.message + ", " + err.name + ", " + err.stack;
      } else {
        this.publish = "publish event with data success";
      }
    })
  }


  build() {
    Column({space: 10}) {
      Button("创建订阅者")
        .size({width: 260, height: 50})
        .onClick(() => {
          this.createSubscriber();
        })
      Button("订阅公共事件")
        .size({width: 260, height: 50})
        .onClick(() => {
          this.subscribe();
        })

      Button("取消订阅")
        .size({width: 260, height: 50})
        .onClick(() => {
          this.unsubscribe();
        })

      Text(this.text)
        .size({width: 260, height: 150})
        .fontSize(22)
        .backgroundColor("#dbdbdb")

      Divider()
        .size({width: 260, height: 5})

      Button("发布公共事件")
        .size({width: 260, height: 50})
        .onClick(() => {
          this.publishEvent();
        })

      Button("发布公共事件指定公共信息")
        .size({width: 260, height: 50})
        .onClick(() => {
          this.publishEventWithData();
        })

      Text(this.publish)
        .size({width: 260, height: 150})
        .fontSize(22)
        .backgroundColor("#dbdbdb")

    }
    .padding(10)
    .size({width: "100%", height: '100%'})
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

样例很简单,首先创建一个订阅者,然后订阅指定事件,当有匹配的事件时,会回调给订阅者,运行结果如下图所示:

11_1

样例简单演示了发送自定义事件的操作, @ohos.commonEvent 模块下的 Support 类内定义了许多系统事件,订阅系统事件只需要把自定义的事件名称替换成 Support 内部支持的事件名称即可。

# 11.1.4:小结

本节简单介绍了事件的订阅和发布, @ohos.commonEvent 模块不仅可以订阅系统事件,还可以订阅和发布自定义事件,最后请读者思考一下:根据前边章节讲述的ArkUI的状态管理,比如跨页面数据更新可不可以使用事件订阅机制来实现?

(adsbygoogle = window.adsbygoogle || []).push({});
请作者喝杯咖啡

津公网安备 12011402001367号

津ICP备2020008934号-2

中央网信办互联网违法和不良信息举报中心

天津市互联网违法和不良信息举报中心