1# 订阅应用事件(C/C++)
2
3HiAppEvent提供了事件订阅接口,用于本地获取应用事件。
4
5## 接口说明
6API接口的具体使用说明(参数使用限制、具体取值范围等)请参考[HiAppEvent](../reference/apis-performance-analysis-kit/_hi_app_event.md#hiappevent)。
7
8**打点接口功能介绍:**
9
10| 接口名                                                       | 描述                                 |
11| ------------------------------------------------------------ | ------------------------------------ |
12| int OH_HiAppEvent_Write(const char \*domain, const char \*name, enum EventType type, const ParamList list) | 实现对参数为列表类型的应用事件打点。 |
13
14**订阅接口功能介绍:**
15
16| 接口名                                                       | 描述                                         |
17| ------------------------------------------------------------ | -------------------------------------------- |
18| int OH_HiAppEvent_AddWatcher (HiAppEvent_Watcher \*watcher)  | 添加应用事件观察者,以添加对应用事件的订阅。 |
19| int OH_HiAppEvent_RemoveWatcher (HiAppEvent_Watcher \*watcher) | 移除应用事件观察者,以移除对应用事件的订阅。 |
20
21## 开发步骤
22
23以实现对用户点击按钮行为的事件打点及订阅为例,说明开发步骤:
24
251. 新建Native C++工程,并将jsoncpp导入到新建工程内,目录结构如下:
26
27   ```yml
28   entry:
29     src:
30       main:
31         cpp:
32           - json:
33               - json.h
34               - json-forwards.h
35           - types:
36               libentry:
37                 - index.d.ts
38           - CMakeLists.txt
39           - napi_init.cpp
40           - jsoncpp.cpp
41         ets:
42           - entryability:
43               - EntryAbility.ets
44           - pages:
45               - Index.ets
46   ```
47
482. 编辑"CMakeLists.txt"文件,添加源文件及动态库:
49
50   ```cmake
51   # 新增jsoncpp.cpp(解析订阅事件中的json字符串)源文件
52   add_library(entry SHARED napi_init.cpp jsoncpp.cpp)
53   # 新增动态库依赖libhiappevent_ndk.z.solibhilog_ndk.z.so(日志输出)
54   target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libhiappevent_ndk.z.so)
55   ```
56
573. 编辑"napi_init.cpp"文件,导入依赖的文件,并定义LOG_TAG:
58
59   ```c++
60   #include "napi/native_api.h"
61   #include "json/json.h"
62   #include "hilog/log.h"
63   #include "hiappevent/hiappevent.h"
64
65   #undef LOG_TAG
66   #define LOG_TAG "testTag"
67   ```
68
694. 订阅应用事件:
70
71   - onReceive类型观察者:
72
73     编辑"napi_init.cpp"文件,定义onReceive类型观察者相关方法:
74
75     ```c++
76     static HiAppEvent_Watcher *appEventWatcher;
77
78     static void OnReceive(const char *domain, const struct HiAppEvent_AppEventGroup *appEventGroups, uint32_t groupLen) {
79         for (int i = 0; i < groupLen; ++i) {
80             for (int j = 0; j < appEventGroups[i].infoLen; ++j) {
81                 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.domain=%{public}s", appEventGroups[i].appEventInfos[j].domain);
82                 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.name=%{public}s", appEventGroups[i].appEventInfos[j].name);
83                 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.eventType=%{public}d", appEventGroups[i].appEventInfos[j].type);
84                 if (strcmp(appEventGroups[i].appEventInfos[j].domain, "button") == 0 &&
85                     strcmp(appEventGroups[i].appEventInfos[j].name, "click") == 0) {
86                     Json::Value params;
87                     Json::Reader reader(Json::Features::strictMode());
88                     if (reader.parse(appEventGroups[i].appEventInfos[j].params, params)) {
89                         auto time = params["click_time"].asInt64();
90                         OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.params.click_time=%{public}lld", time);
91                     }
92                 }
93             }
94         }
95     }
96
97     static napi_value RegisterWatcher(napi_env env, napi_callback_info info) {
98         // 开发者自定义观察者名称,系统根据不同的名称来识别不同的观察者。
99         appEventWatcher = OH_HiAppEvent_CreateWatcher("onReceiverWatcher");
100         // 设置订阅的事件名称为click。
101         const char *names[] = {"click"};
102         // 开发者订阅感兴趣的应用事件,此处订阅了button相关事件。
103         OH_HiAppEvent_SetAppEventFilter(appEventWatcher, "button", 0, names, 1);
104         // 开发者设置已实现的回调函数,观察者接收到事件后回立即触发OnReceive回调。
105         OH_HiAppEvent_SetWatcherOnReceive(appEventWatcher, OnReceive);
106         // 使观察者开始监听订阅的事件。
107         OH_HiAppEvent_AddWatcher(appEventWatcher);
108         return {};
109     }
110     ```
111
112   - onTrigger类型观察者:
113
114     编辑"napi_init.cpp"文件,定义OnTrigger类型观察者相关方法:
115
116     ```c++
117     //定义一变量,用来缓存创建的观察者的指针。
118     static HiAppEvent_Watcher *appEventWatcher;
119
120     // 开发者可以自行实现获取已监听到事件的回调函数,其中events指针指向内容仅在该函数内有效。
121     static void OnTake(const char *const *events, uint32_t eventLen) {
122         Json::Reader reader(Json::Features::strictMode());
123         for (int i = 0; i < eventLen; ++i) {
124             OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo=%{public}s", events[i]);
125             Json::Value eventInfo;
126             if (reader.parse(events[i], eventInfo)) {
127                 auto domain = eventInfo["domain_"].asString();
128                 auto name = eventInfo["name_"].asString();
129                 auto type = eventInfo["type_"].asInt();
130                 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.domain=%{public}s", domain.c_str());
131                 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.name=%{public}s", name.c_str());
132                 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.eventType=%{public}d", type);
133                 if (domain == "button" && name == "click") {
134                     auto clickTime = eventInfo["click_time"].asInt64();
135                     OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.params.click_time=%{public}lld", clickTime);
136                 }
137             }
138         }
139     }
140
141     // 开发者可以自行实现订阅回调函数,以便对获取到的事件打点数据进行自定义处理。
142     static void OnTrigger(int row, int size) {
143         // 接收回调后,获取指定数量的已接收事件。
144         OH_HiAppEvent_TakeWatcherData(appEventWatcher, row, OnTake);
145     }
146
147     static napi_value RegisterWatcher(napi_env env, napi_callback_info info) {
148         // 开发者自定义观察者名称,系统根据不同的名称来识别不同的观察者。
149         appEventWatcher = OH_HiAppEvent_CreateWatcher("onTriggerWatcher");
150         // 设置订阅的事件名称为click。
151         const char *names[] = {"click"};
152         // 开发者订阅感兴趣的应用事件,此处订阅了button相关事件。
153         OH_HiAppEvent_SetAppEventFilter(appEventWatcher, "button", 0, names, 1);
154         // 开发者设置已实现的回调函数,需OH_HiAppEvent_SetTriggerCondition设置的条件满足方可触发。
155         OH_HiAppEvent_SetWatcherOnTrigger(appEventWatcher, OnTrigger);
156         // 开发者可以设置订阅触发回调的条件,此处是设置新增事件打点数量为1个时,触发onTrigger回调。
157         OH_HiAppEvent_SetTriggerCondition(appEventWatcher, 1, 0, 0);
158         // 使观察者开始监听订阅的事件。
159         OH_HiAppEvent_AddWatcher(appEventWatcher);
160         return {};
161     }
162     ```
163
1645. 编辑"napi_init.cpp"文件,添加button事件打点接口:
165
166   ```c++
167   static napi_value WriteAppEvent(napi_env env, napi_callback_info info) {
168       auto params = OH_HiAppEvent_CreateParamList();
169       OH_HiAppEvent_AddInt64Param(params, "click_time", time(nullptr));
170       OH_HiAppEvent_Write("button", "click", EventType::BEHAVIOR, params);
171       OH_HiAppEvent_DestroyParamList(params);
172       return {};
173   }
174   ```
175
1766. 编辑"napi_init.cpp"文件,将RegisterWatcher和WriteAppEvent注册为ArkTS接口:
177
178   ```c++
179   static napi_value Init(napi_env env, napi_value exports)
180   {
181       napi_property_descriptor desc[] = {
182           {"registerWatcher", nullptr, RegisterWatcher, nullptr, nullptr, nullptr, napi_default, nullptr},
183           {"writeAppEvent", nullptr, WriteAppEvent, nullptr, nullptr, nullptr, napi_default, nullptr}
184       };
185       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
186       return exports;
187   }
188   ```
189
190   编辑"index.d.ts"文件,定义ArkTS接口:
191
192   ```typescript
193   export const registerWatcher: () => void;
194   export const writeAppEvent: () => void;
195   ```
196
1977. 编辑"EntryAbility.ets"文件,在onCreate()函数中新增接口调用:
198
199   ```typescript
200   // 导入依赖模块
201   import testNapi from 'libentry.so'
202
203   // 在onCreate()函数中新增接口调用
204   // 启动时,注册应用事件观察者
205   testNapi.registerWatcher();
206   ```
207
2088. 编辑"Index.ets"文件,新增按钮触发打点事件:
209
210   ```typescript
211   import testNapi from 'libentry.so'
212
213   Button("button_click").onClick(() => {
214     testNapi.writeAppEvent();
215   })
216   ```
217
2189. 可以在Log窗口看到对应用事件数据的处理日志:
219
220   ```text
221   HiAppEvent eventInfo.domain=button
222   HiAppEvent eventInfo.name=click
223   HiAppEvent eventInfo.eventType=4
224   HiAppEvent eventInfo.params.click_time=1502031843
225   ```
226
22710. 移除应用事件观察者:
228
229    ```c++
230    static napi_value RemoveWatcher(napi_env env, napi_callback_info info) {
231        // 使观察者停止监听事件
232        OH_HiAppEvent_RemoveWatcher(appEventWatcher);
233        return {};
234    }
235    ```
236
23711. 销毁应用事件观察者:
238
239    ```c++
240    static napi_value DestroyWatcher(napi_env env, napi_callback_info info) {
241        // 销毁创建的观察者,并置appEventWatcher为nullptr。
242        OH_HiAppEvent_DestroyWatcher(appEventWatcher);
243        appEventWatcher = nullptr;
244        return {};
245    }
246    ```
247