1# 短时任务(C/C++)
2
3## 场景介绍
4
5应用退至后台一小段时间后,应用进程会被挂起,无法执行对应的任务。如果应用在后台仍需要执行耗时不长的任务,如状态保存等,可以通过本文申请短时任务,扩展应用在后台的运行时间。
6
7## 接口说明
8
9常用接口如下表所示。
10
11
12| 接口名 | 描述 |
13| -------- | -------- |
14| int32_t OH_BackgroundTaskManager_RequestSuspendDelay(const char *reason, TransientTask_Callback callback, TransientTask_DelaySuspendInfo *info); | 申请短时任务。 |
15| int32_t OH_BackgroundTaskManager_GetRemainingDelayTime(int32_t requestId, int32_t *delayTime); | 获取对应短时任务的剩余时间。 |
16| int32_t OH_BackgroundTaskManager_CancelSuspendDelay(int32_t requestId); | 取消短时任务。 |
17
18## 开发步骤
19
20### 在napi_init.cpp文件中封装接口并注册模块
21
221. 封装函数
23
24   ```C
25   #include "napi/native_api.h"
26   #include "transient_task/transient_task_api.h"
27
28   TransientTask_DelaySuspendInfo delaySuspendInfo;
29
30   static void callback(void)
31   {
32      // 短时任务即将结束,业务在这里取消短时任务
33      OH_BackgroundTaskManager_CancelSuspendDelay(delaySuspendInfo.requestId);
34   }
35
36   // 申请短时任务
37   static napi_value RequestSuspendDelay(napi_env env, napi_callback_info info)
38   {
39         napi_value result;
40         int32_t res = OH_BackgroundTaskManager_RequestSuspendDelay("test", callback, &delaySuspendInfo);
41         if (res == 0) {
42            napi_create_int32(env, delaySuspendInfo.requestId, &result);
43         } else {
44            napi_create_int32(env, -1, &result);
45         }
46         return result;
47   }
48
49   // 获取剩余时间
50   static napi_value GetRemainingDelayTime(napi_env env, napi_callback_info info)
51   {
52         napi_value result;
53         int32_t delayTime = 0;
54         int32_t res = OH_BackgroundTaskManager_GetRemainingDelayTime(delaySuspendInfo.requestId, &delayTime);
55         if (res == 0) {
56            napi_create_int32(env, delayTime, &result);
57         } else {
58            napi_create_int32(env, -1, &result);
59         }
60         return result;
61   }
62
63   // 取消短时任务
64   static napi_value CancelSuspendDelay(napi_env env, napi_callback_info info)
65   {
66         napi_value result;
67         int32_t res = OH_BackgroundTaskManager_CancelSuspendDelay(delaySuspendInfo.requestId);
68         napi_create_int32(env, res, &result);
69         return result;
70   }
71
72   ```
73
742. 注册函数
75
76   ```C
77   EXTERN_C_START
78   static napi_value Init(napi_env env, napi_value exports)
79   {
80       napi_property_descriptor desc[] = {
81           {"RequestSuspendDelay", nullptr, RequestSuspendDelay, nullptr, nullptr, nullptr, napi_default, nullptr},
82           {"GetRemainingDelayTime", nullptr, GetRemainingDelayTime, nullptr, nullptr, nullptr, napi_default, nullptr},
83           {"CancelSuspendDelay", nullptr, CancelSuspendDelay, nullptr, nullptr, nullptr, napi_default, nullptr},
84       };
85       napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
86       return exports;
87   }
88   EXTERN_C_END
89   ```
90
913. 注册模块
92
93   ```C
94   static napi_module demoModule = {
95       .nm_version = 1,
96       .nm_flags = 0,
97       .nm_filename = nullptr,
98       .nm_register_func = Init,
99       .nm_modname = "entry",
100       .nm_priv = ((void*)0),
101       .reserved = { 0 },
102   };
103
104   extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
105   {
106       napi_module_register(&demoModule);
107   }
108   ```
109
110### 在index.d.ts文件中声明函数
111
112   ```ts
113   export const RequestSuspendDelay: () => number;
114   export const GetRemainingDelayTime: () => number;
115   export const CancelSuspendDelay: () => number;
116   ```
117
118### 在index.ets文件中调用函数
119
120   ```ts
121   import testTransientTask from 'libentry.so';
122
123   @Entry
124   @Component
125   struct Index {
126     @State message: string = '';
127
128     build() {
129       Row() {
130         Column() {
131           Text(this.message)
132             .fontSize(50)
133             .fontWeight(FontWeight.Bold)
134           Button('申请短时任务').onClick(event => {
135             this.RequestSuspendDelay();
136           })
137           Button('获取剩余时间').onClick(event =>{
138             this.GetRemainingDelayTime();
139           })
140           Button('取消短时任务').onClick(event =>{
141             this.CancelSuspendDelay();
142           })
143         }
144         .width('100%')
145        }
146       .height('100%')
147     }
148
149     RequestSuspendDelay() {
150       let requestId = testTransientTask.RequestSuspendDelay();
151       console.log("The return requestId is " + requestId);
152     }
153
154     GetRemainingDelayTime() {
155       let time = testTransientTask.GetRemainingDelayTime();
156       console.log("The time is " + time);
157     }
158
159     CancelSuspendDelay() {
160       let ret = testTransientTask.CancelSuspendDelay();
161       console.log("The ret is " + ret);
162     }
163   }
164
165   ```
166
167### 配置库依赖
168
169配置`CMakeLists.txt`,本模块需要用到的共享库是`libtransient_task.so`,在工程自动生成的`CMakeLists.txt`中的`target_link_libraries`中添加此共享库。
170
171   ```txt
172   target_link_libraries(entry PUBLIC libace_napi.z.so libtransient_task.so)
173   ```
174
175## 测试步骤
176
1771. 连接设备并运行程序。
178
1792. 点击 `申请短时任务` 按钮,控制台会打印日志,示例如下:
180
181   ```
182   The return requestId is 1
183   ```
184
1853. 点击 `获取剩余时间` 按钮,控制台会打印日志,示例如下:
186
187   ```
188   The return requestId is 18000
189   ```
1904. 点击 `取消短时任务` 按钮,控制台会打印日志,示例如下:
191
192   ```
193   The ret is 0
194   ```
195> **说明**
196>
197>申请短时任务的按钮,不可连续点击超过3次,否则会报错。使用过程中更多的约束与限制请参考[短时任务(ArkTS)](transient-task.md#约束与限制)。
198