1# Subscribing to Application Killed Events (C/C++) 2 3<!--Kit: Performance Analysis Kit--> 4<!--Subsystem: HiviewDFX--> 5<!--Owner: @shead-master--> 6<!--Designer: @peterhuangyu--> 7<!--Tester: @gcw_KuLfPSbe--> 8<!--Adviser: @foryourself--> 9 10## Event Specifications 11 12For details, see [Application Killed Event Overview](./hiappevent-watcher-app-killed-events.md). 13 14## Available APIs 15 16For details about how to use the APIs (such as parameter usage restrictions and value ranges), see [HiAppEvent](../reference/apis-performance-analysis-kit/capi-hiappevent-h.md). 17 18**Subscription APIs** 19 20| Name | Description | 21| ------------------------------------------------------------ | -------------------------------------------- | 22| int OH_HiAppEvent_AddWatcher(HiAppEvent_Watcher *watcher) | Adds a watcher to listen for application events.| 23| int OH_HiAppEvent_RemoveWatcher(HiAppEvent_Watcher *watcher) | Removes a watcher for the specified application events.| 24 25## How to Develop 26 271. Create a native C++ project and import the **jsoncpp** file to the project. The directory structure is as follows: 28 29 ```yml 30 entry: 31 src: 32 main: 33 cpp: 34 - json: 35 - json.h 36 - json-forwards.h 37 - types: 38 libentry: 39 - index.d.ts 40 - CMakeLists.txt 41 - napi_init.cpp 42 - jsoncpp.cpp 43 ets: 44 - entryability: 45 - EntryAbility.ets 46 - pages: 47 - Index.ets 48 ``` 49 502. In the **CMakeLists.txt** file, add the source file and dynamic libraries. 51 52 ```cmake 53 # Add the **jsoncpp.cpp** file, which is used to parse the JSON strings in the subscription events. 54 add_library(entry SHARED napi_init.cpp jsoncpp.cpp) 55 # Add **libhiappevent_ndk.z.so** and **libhilog_ndk.z.so** (log output). 56 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libhiappevent_ndk.z.so) 57 ``` 58 593. Import the dependencies to the **napi_init.cpp** file, and define **LOG_TAG**. 60 61 ```c++ 62 #include "napi/native_api.h" 63 #include "json/json.h" 64 #include "hilog/log.h" 65 #include "hiappevent/hiappevent.h" 66 #include "hiappevent/hiappevent_event.h" 67 #include <thread> 68 69 #undef LOG_TAG 70 #define LOG_TAG "testTag" 71 ``` 72 734. Subscribe to system events. 74 75 - Watcher of the **onReceive** type. 76 77 In the **napi_init.cpp** file, define the methods related to the watcher of the **onReceive** type and add the native memory leak method. 78 79 ```c++ 80 // Define a variable to cache the pointer to the created watcher. 81 static HiAppEvent_Watcher *systemEventWatcher; 82 83 static void OnReceive(const char *domain, const struct HiAppEvent_AppEventGroup *appEventGroups, uint32_t groupLen) { 84 for (int i = 0; i < groupLen; ++i) { 85 for (int j = 0; j < appEventGroups[i].infoLen; ++j) { 86 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.domain=%{public}s", 87 appEventGroups[i].appEventInfos[j].domain); 88 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.name=%{public}s", 89 appEventGroups[i].appEventInfos[j].name); 90 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.eventType=%{public}d", 91 appEventGroups[i].appEventInfos[j].type); 92 if (strcmp(appEventGroups[i].appEventInfos[j].domain, DOMAIN_OS) == 0 && 93 strcmp(appEventGroups[i].appEventInfos[j].name, EVENT_APP_KILLED) == 0) { 94 Json::Value params; 95 Json::Reader reader(Json::Features::strictMode()); 96 Json::FastWriter writer; 97 if (reader.parse(appEventGroups[i].appEventInfos[j].params, params)) { 98 auto time = params["time"].asInt64(); 99 auto reason = params["reason"].asString(); 100 auto foreground = params["foreground"].asString(); 101 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.params.time=%{public}lld", time); 102 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.params.reason=%{public}s", 103 reason.c_str()); 104 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent eventInfo.params.foreground=%{public}s", 105 foreground.c_str()); 106 } 107 } 108 } 109 } 110 } 111 112 static napi_value RegisterWatcher(napi_env env, napi_callback_info info) { 113 OH_LOG_INFO(LogType::LOG_APP, "HiAppEvent RegisterWatcher"); 114 // Set the watcher name. The system identifies different watchers based on their names. 115 systemEventWatcher = OH_HiAppEvent_CreateWatcher("onReceiverWatcher"); 116 // Set the event to watch to EVENT_APP_KILLED. 117 const char *names[] = {EVENT_APP_KILLED}; 118 // Add the events to watch, for example, system events. 119 OH_HiAppEvent_SetAppEventFilter(systemEventWatcher, DOMAIN_OS, 0, names, 1); 120 // Set the implemented callback. After receiving the event, the watcher immediately triggers the OnReceive callback. 121 OH_HiAppEvent_SetWatcherOnReceive(systemEventWatcher, OnReceive); 122 // Add a watcher to listen for the specified event. 123 OH_HiAppEvent_AddWatcher(systemEventWatcher); 124 return {}; 125 } 126 ``` 127 1285. Implement the **Leak** API. (This API is used only for fault injection and self-verification and does not need to be integrated into the service logic.) 129 130 ```c++ 131 static void NativeLeak() 132 { 133 constexpr int leak_size_per_time = 500000; 134 while (true) { 135 char *p = (char *)malloc(leak_size_per_time + 1); 136 if (!p) { 137 break; 138 } 139 memset(p, 'a', leak_size_per_time); 140 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 141 } 142 } 143 144 static napi_value Leak(napi_env env, napi_callback_info info) { 145 std::thread t1(NativeLeak); 146 t1.detach(); 147 return {}; 148 } 149 ``` 150 1516. In the **napi_init.cpp** file, register **RegisterWatcher** and **Leak** as ArkTS APIs. 152 153 ```c++ 154 static napi_value Init(napi_env env, napi_value exports) 155 { 156 napi_property_descriptor desc[] = { 157 { "registerWatcher", nullptr, RegisterWatcher, nullptr, nullptr, nullptr, napi_default, nullptr }, 158 { "leak", nullptr, Leak, nullptr, nullptr, nullptr, napi_default, nullptr }, 159 }; 160 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 161 return exports; 162 } 163 ``` 164 165 In the **index.d.ts** file, define the ArkTS API. 166 167 ```typescript 168 export const registerWatcher: () => void; 169 export const leak: () => void; 170 ``` 171 1727. In the **entry/src/main/ets/entryability/EntryAbility.ets** file, add the following interface invocation to **onCreate()**. 173 174 ```typescript 175 // Import the dependent module. 176 import testNapi from 'libentry.so'; 177 178 // Add the API to onCreate(). 179 // Register the system event watcher at startup. 180 testNapi.registerWatcher(); 181 182 // Trigger a leak when the button is operated or started. 183 testNapi.leak(); 184 ``` 185 1868. Click the **Run** button in DevEco Studio to run the project. After the leak is triggered, wait for 2 to 3 minutes and the application exits. 187 1889. After the application is killed, open the application again. The killed event is reported, and the system calls **onReceive()**. You can view the following event information in the **Log** window. 189 190 ```text 191 HiAppEvent eventInfo.domain=OS 192 HiAppEvent eventInfo.name=APP_KILLED 193 HiAppEvent eventInfo.eventType=2 194 HiAppEvent eventInfo.params.time=1717597063727 195 HiAppEvent eventInfo.params.reason="RssThresholdKiller" 196 HiAppEvent eventInfo.params.foreground=true 197 ``` 198 199 > **NOTE** 200 > 201 > Based on the error log information, you can check the [specific cause of the killed event](./hiappevent-watcher-app-killed-events.md). 202 20310. Remove the event watcher. 204 205 ```c++ 206 static napi_value RemoveWatcher(napi_env env, napi_callback_info info) { 207 // Remove the watcher. 208 OH_HiAppEvent_RemoveWatcher(systemEventWatcher); 209 return {}; 210 } 211 ``` 212 21311. Destroy the event watcher. 214 215 ```c++ 216 static napi_value DestroyWatcher(napi_env env, napi_callback_info info) { 217 // Destroy the created watcher and set systemEventWatcher to nullptr. 218 OH_HiAppEvent_DestroyWatcher(systemEventWatcher); 219 systemEventWatcher = nullptr; 220 return {}; 221 } 222 ``` 223