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 "json/json.h" 61 # include "hilog/log.h" 62 # include "hiappevent/hiappevent.h" 63 64 # undef LOG_TAG 65 # define LOG_TAG "testTag" 66 ``` 67 684. Subscribe to application events. 69 70 - Watcher of the onReceive type: 71 72 In the **napi_init.cpp** file, define the methods related to the watcher of the onReceive type. 73 74 ```c++ 75 static HiAppEvent_Watcher *appEventWatcher; 76 77 static void OnReceive(const char *domain, const struct HiAppEvent_AppEventGroup *appEventGroups, uint32_t groupLen) { 78 for (int i = 0; i < groupLen; ++i) { 79 for (int j = 0; j < appEventGroups[i].infoLen; ++j) { 80 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.domain=%{public}s", appEventGroups[i].appEventInfos[j].domain); 81 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.name=%{public}s", appEventGroups[i].appEventInfos[j].name); 82 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.eventType=%{public}d", appEventGroups[i].appEventInfos[j].type); 83 if (strcmp(appEventGroups[i].appEventInfos[j].domain, "button") == 0 && 84 strcmp(appEventGroups[i].appEventInfos[j].name, "click") == 0) { 85 Json::Value params; 86 Json::Reader reader(Json::Features::strictMode()); 87 if (reader.parse(appEventGroups[i].appEventInfos[j].params, params)) { 88 auto time = params["click_time"].asInt64(); 89 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.params.click_time=%{public}lld", time); 90 } 91 } 92 } 93 } 94 } 95 96 static napi_value RegisterWatcher(napi_env env, napi_callback_info info) { 97 // Set the watcher name. The system identifies different watchers based on their names. 98 appEventWatcher = OH_HiAppEvent_CreateWatcher("onReceiverWatcher"); 99 // Set the name of the subscribed event to click. 100 const char *names[] = {"click"}; 101 // Add the system events to watch, for example, events related to button. 102 OH_HiAppEvent_SetAppEventFilter(appEventWatcher, "button", 0, names, 1); 103 // Set the implemented callback. After receiving the event, the watcher immediately triggers the OnReceive callback. 104 OH_HiAppEvent_SetWatcherOnReceive(appEventWatcher, OnReceive); 105 // Add a watcher to listen for the specified event. 106 OH_HiAppEvent_AddWatcher(appEventWatcher); 107 return {}; 108 } 109 ``` 110 111 - Watcher of the onTrigger type: 112 113 In the **napi_init.cpp** file, define the methods related to the watcher of the OnTrigger type. 114 115 ```c++ 116 // Define a variable to cache the pointer to the created watcher. 117 static HiAppEvent_Watcher *appEventWatcher; 118 119 // Implement the callback function used to return the listened events. The content pointed to by the events pointer is valid only in this function. 120 static void OnTake(const char *const *events, uint32_t eventLen) { 121 Json::Reader reader(Json::Features::strictMode()); 122 for (int i = 0; i < eventLen; ++i) { 123 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo=%{public}s", events[i]); 124 Json::Value eventInfo; 125 if (reader.parse(events[i], eventInfo)) { 126 auto domain = eventInfo["domain_"].asString(); 127 auto name = eventInfo["name_"].asString(); 128 auto type = eventInfo["type_"].asInt(); 129 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.domain=%{public}s", domain.c_str()); 130 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.name=%{public}s", name.c_str()); 131 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.eventType=%{public}d", type); 132 if (domain == "button" && name == "click") { 133 auto clickTime = eventInfo["click_time"].asInt64(); 134 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.params.click_time=%{public}lld", clickTime); 135 } 136 } 137 } 138 } 139 140 // Implement the subscription callback function to apply custom processing to the obtained event logging data. 141 static void OnTrigger(int row, int size) { 142 // After the callback is received, obtain the specified number of received events. 143 OH_HiAppEvent_TakeWatcherData(appEventWatcher, row, OnTake); 144 } 145 146 static napi_value RegisterWatcher(napi_env env, napi_callback_info info) { 147 // Set the watcher name. The system identifies different watchers based on their names. 148 appEventWatcher = OH_HiAppEvent_CreateWatcher("onTriggerWatcher"); 149 // Set the name of the subscribed event to click. 150 const char *names[] = {"click"}; 151 // Add the system events to watch, for example, events related to button. 152 OH_HiAppEvent_SetAppEventFilter(appEventWatcher, "button", 0, names, 1); 153 // Set the implemented callback function. The callback function will be triggered when the conditions set by OH_HiAppEvent_SetTriggerCondition are met. 154 OH_HiAppEvent_SetWatcherOnTrigger(appEventWatcher, OnTrigger); 155 // Set the conditions for triggering the subscription callback. For example, trigger this onTrigger callback when the number of new event logs is 1. 156 OH_HiAppEvent_SetTriggerCondition(appEventWatcher, 1, 0, 0); 157 // Add a watcher to listen for the specified event. 158 OH_HiAppEvent_AddWatcher(appEventWatcher); 159 return {}; 160 } 161 ``` 162 1635. In the **napi_init.cpp** file, add an API for logging button onclick events. 164 165 ```c++ 166 static napi_value WriteAppEvent(napi_env env, napi_callback_info info) { 167 auto params = OH_HiAppEvent_CreateParamList(); 168 OH_HiAppEvent_AddInt64Param(params, "click_time", time(nullptr)); 169 OH_HiAppEvent_Write("button", "click", EventType::BEHAVIOR, params); 170 OH_HiAppEvent_DestroyParamList(params); 171 return {}; 172 } 173 ``` 174 1756. In the **napi_init.cpp** file, register **RegisterWatcher** and **WriteAppEvent** as ArkTS APIs. 176 177 ```c++ 178 static napi_value Init(napi_env env, napi_value exports) 179 { 180 napi_property_descriptor desc[] = { 181 {"registerWatcher", nullptr, RegisterWatcher, nullptr, nullptr, nullptr, napi_default, nullptr}, 182 {"writeAppEvent", nullptr, WriteAppEvent, nullptr, nullptr, nullptr, napi_default, nullptr} 183 }; 184 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 185 return exports; 186 } 187 ``` 188 189 In the **index.d.ts** file, define ArkTS APIs. 190 191 ```typescript 192 export const registerWatcher: () => void; 193 export const writeAppEvent: () => void; 194 ``` 195 1967. In the **EntryAbility.ets** file, add the following interface invocation to **onCreate()**. 197 198 ```typescript 199 // Import the dependent module. 200 import testNapi from 'libentry.so' 201 202 // Add the interface invocation to onCreate(). 203 // Register the application event watcher at startup. 204 testNapi.registerWatcher(); 205 ``` 206 2078. In the **Index.ets** file, add a button to trigger the button onclick event. 208 209 ```typescript 210 import testNapi from 'libentry.so' 211 212 Button("button_click").onClick(() => { 213 testNapi.writeAppEvent(); 214 }) 215 ``` 216 2179. You can view the processing logs of application event data in the **Log** window. 218 219 ```text 220 HiAppEvent eventInfo.domain=button 221 HiAppEvent eventInfo.name=click 222 HiAppEvent eventInfo.eventType=4 223 HiAppEvent eventInfo.params.click_time=1502031843 224 ``` 225 22610. Remove the application event watcher. 227 228 ```c++ 229 static napi_value RemoveWatcher(napi_env env, napi_callback_info info) { 230 // Remove the watcher. 231 OH_HiAppEvent_RemoveWatcher(appEventWatcher); 232 return {}; 233 } 234 ``` 235 23611. Destroy the application event watcher. 237 238 ```c++ 239 static napi_value DestroyWatcher(napi_env env, napi_callback_info info) { 240 // Destroy the created watcher and set appEventWatcher to nullptr. 241 OH_HiAppEvent_DestroyWatcher(appEventWatcher); 242 appEventWatcher = nullptr; 243 return {}; 244 } 245 ``` 246 247<!--no_check-->