1# Subscribing to Application Events (C/C++) 2 3HiAppEvent provides APIs for subscribing to application events. 4 5## Available APIs 6For details about how to use the APIs (such as parameter usage restrictions and value ranges), see [HiAppEvent](../reference/apis-performance-analysis-kit/_hi_app_event.md#hiappevent). 7 8**Event Logging APIs** 9 10| API | Description | 11| ------------------------------------------------------------ | ------------------------------------ | 12| int OH_HiAppEvent_Write(const char \*domain, const char \*name, enum EventType type, const ParamList list) | Logs application events whose parameters are of the list type.| 13 14**Subscription APIs** 15 16| API | Description | 17| ------------------------------------------------------------ | -------------------------------------------- | 18| int OH_HiAppEvent_AddWatcher (HiAppEvent_Watcher \*watcher) | Adds a watcher to listen for application events.| 19| int OH_HiAppEvent_RemoveWatcher (HiAppEvent_Watcher \*watcher) | Removes a watcher to unsubscribe from application events.| 20 21## How to Develop 22 23The following describes how to log and subscribe to button onclick events. 24 251. Create a native C++ project and import the **jsoncpp** file to the project. The directory structure is as follows: 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. In the **CMakeLists.txt** file, add the source file and dynamic libraries. 49 50 ```cmake 51 # Add the jsoncpp.cpp file, which is used to parse the JSON strings in the subscription events. 52 add_library(entry SHARED napi_init.cpp jsoncpp.cpp) 53 # Add libhiappevent_ndk.z.so and libhilog_ndk.z.so (log output). 54 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libhiappevent_ndk.z.so) 55 ``` 56 573. Import the dependencies to the **napi_init.cpp** file, and define **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. Subscribe to application events. 70 71 - Watcher of the onReceive type: 72 73 In the **napi_init.cpp** file, define the methods related to the watcher of the onReceive type. 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 // Set the watcher name. The system identifies different watchers based on their names. 99 appEventWatcher = OH_HiAppEvent_CreateWatcher("onReceiverWatcher"); 100 // Set the name of the subscribed event to click. 101 const char *names[] = {"click"}; 102 // Add the system events to watch, for example, events related to button. 103 OH_HiAppEvent_SetAppEventFilter(appEventWatcher, "button", 0, names, 1); 104 // Set the implemented callback. After receiving the event, the watcher immediately triggers the OnReceive callback. 105 OH_HiAppEvent_SetWatcherOnReceive(appEventWatcher, OnReceive); 106 // Add a watcher to listen for the specified event. 107 OH_HiAppEvent_AddWatcher(appEventWatcher); 108 return {}; 109 } 110 ``` 111 112 - Watcher of the onTrigger type: 113 114 In the **napi_init.cpp** file, define the methods related to the watcher of the OnTrigger type. 115 116 ```c++ 117 // Define a variable to cache the pointer to the created watcher. 118 static HiAppEvent_Watcher *appEventWatcher; 119 120 // Implement the callback function used to return the listened events. The content pointed to by the events pointer is valid only in this function. 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 // Implement the subscription callback function to apply custom processing to the obtained event logging data. 142 static void OnTrigger(int row, int size) { 143 // After the callback is received, obtain the specified number of received events. 144 OH_HiAppEvent_TakeWatcherData(appEventWatcher, row, OnTake); 145 } 146 147 static napi_value RegisterWatcher(napi_env env, napi_callback_info info) { 148 // Set the watcher name. The system identifies different watchers based on their names. 149 appEventWatcher = OH_HiAppEvent_CreateWatcher("onTriggerWatcher"); 150 // Set the name of the subscribed event to click. 151 const char *names[] = {"click"}; 152 // Add the system events to watch, for example, events related to button. 153 OH_HiAppEvent_SetAppEventFilter(appEventWatcher, "button", 0, names, 1); 154 // Set the implemented callback function. The callback function will be triggered when the conditions set by OH_HiAppEvent_SetTriggerCondition are met. 155 OH_HiAppEvent_SetWatcherOnTrigger(appEventWatcher, OnTrigger); 156 // Set the conditions for triggering the subscription callback. For example, trigger this onTrigger callback when the number of new event logs is 1. 157 OH_HiAppEvent_SetTriggerCondition(appEventWatcher, 1, 0, 0); 158 // Add a watcher to listen for the specified event. 159 OH_HiAppEvent_AddWatcher(appEventWatcher); 160 return {}; 161 } 162 ``` 163 1645. In the **napi_init.cpp** file, add an API for logging button onclick events. 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. In the **napi_init.cpp** file, register **RegisterWatcher** and **WriteAppEvent** as ArkTS APIs. 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 In the **index.d.ts** file, define ArkTS APIs. 191 192 ```typescript 193 export const registerWatcher: () => void; 194 export const writeAppEvent: () => void; 195 ``` 196 1977. In the **EntryAbility.ets** file, add the following interface invocation to **onCreate()**. 198 199 ```typescript 200 // Import the dependent module. 201 import testNapi from 'libentry.so' 202 203 // Add the interface invocation to onCreate(). 204 // Register the application event watcher at startup. 205 testNapi.registerWatcher(); 206 ``` 207 2088. In the **Index.ets** file, add a button to trigger the button onclick event. 209 210 ```typescript 211 import testNapi from 'libentry.so' 212 213 Button("button_click").onClick(() => { 214 testNapi.writeAppEvent(); 215 }) 216 ``` 217 2189. You can view the processing logs of application event data in the **Log** window. 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. Remove the application event watcher. 228 229 ```c++ 230 static napi_value RemoveWatcher(napi_env env, napi_callback_info info) { 231 // Remove the watcher. 232 OH_HiAppEvent_RemoveWatcher(appEventWatcher); 233 return {}; 234 } 235 ``` 236 23711. Destroy the application event watcher. 238 239 ```c++ 240 static napi_value DestroyWatcher(napi_env env, napi_callback_info info) { 241 // Destroy the created watcher and set appEventWatcher to nullptr. 242 OH_HiAppEvent_DestroyWatcher(appEventWatcher); 243 appEventWatcher = nullptr; 244 return {}; 245 } 246 ``` 247