• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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