• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# @ohos.app.ability.childProcessManager (子进程管理)
2<!--Kit: Ability Kit-->
3<!--Subsystem: Ability-->
4<!--Owner: @SKY2001-->
5<!--Designer: @jsjzju-->
6<!--Tester: @lixueqing513-->
7<!--Adviser: @huipeizi-->
8
9childProcessManager模块提供子进程管理能力,支持子进程创建和启动操作。
10
11创建的子进程会随着父进程的退出而退出,无法脱离父进程独立运行。
12
13> **说明:**
14>
15> 本模块首批接口从API version 11开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
16>
17> 本模块接口仅可在Stage模型下使用。
18
19## 约束限制
20
21- 本模块中的接口当前仅支持2in1、tablet设备。
22
23- 通过本模块中接口创建的子进程有如下限制:
24  - 创建的子进程不支持创建UI界面。
25  - 创建的子进程不支持依赖Context的API调用(包括Context模块自身API及将Context实例作为入参的API)。
26  - 创建的子进程内不支持再次创建子进程。
27
28- 通过本模块中定义的创建子进程的接口和[native_child_process.h](capi-native-child-process-h.md)中定义的创建子进程的接口启动的子进程总数最大为512个(系统资源充足情况下),其中[startChildProcess](#childprocessmanagerstartchildprocess)接口在SELF_FORK模式下启动的子进程不计入总数内。
29
30## 导入模块
31
32```ts
33import { childProcessManager } from '@kit.AbilityKit';
34```
35
36## StartMode
37
38子进程启动模式枚举。
39
40**系统能力**:SystemCapability.Ability.AbilityRuntime.Core
41
42| 名称                       | 值                             | 说明                              |
43| --------                     |  -----------------               |  -----------------               |
44| SELF_FORK |  0   | 从App自身进程Fork子进程。以该模式启动的子进程会继承父进程资源,不能使用Binder IPC和其他进程通信,否则会导致子进程崩溃退出。 |
45| APP_SPAWN_FORK |  1   | 从AppSpawn Fork子进程。以该模式启动的子进程不会继承父进程资源,可以使用Binder IPC和其他进程通信。 |
46
47## childProcessManager.startChildProcess
48
49startChildProcess(srcEntry: string, startMode: StartMode): Promise&lt;number&gt;
50
51启动[ArkTS子进程](../../application-models/ability-terminology.md#arkts子进程),使用Promise异步回调。
52
53
54> **说明:**
55>
56> 调用该接口创建子进程成功会返回子进程pid,然后执行子进程的[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)函数,[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)函数执行完后子进程会自动销毁。
57>
58> 调用该接口创建的子进程不支持异步ArkTS API调用,仅支持同步ArkTS API调用。
59
60**系统能力**:SystemCapability.Ability.AbilityRuntime.Core
61
62**参数:**
63
64  | 参数名 | 类型 | 必填 | 说明 |
65  | -------- | -------- | -------- | -------- |
66  | srcEntry | string | 是 | 子进程源文件路径,只支持源文件放在entry类型的模块中,以src/main为根目录。例如子进程文件在entry模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"./ets/process/DemoProcess.ets"。<br/>另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) |
67  | startMode | [StartMode](#startmode) | 是 | 子进程启动模式。 |
68
69**返回值:**
70
71  | 类型 | 说明 |
72  | -------- | -------- |
73  | Promise&lt;number&gt; | Promise对象,返回子进程pid。 |
74
75**错误码**:
76
77  以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)和[元能力子系统错误码](errorcode-ability.md)。
78
79| 错误码ID | 错误信息 |
80| ------- | -------- |
81| 401 | Parameter error. Possible causes: 1.Mandatory parameters are left unspecified; 2.Incorrect parameter types; 3.Parameter verification failed. |
82| 16000050 | Internal error. |
83| 16000061  | Operation not supported. |
84| 16000062  | The number of child processes exceeds the upper limit. |
85
86**示例:**
87
88```ts
89// 在entry模块的src/main/ets/process下创建DemoProcess.ets子进程类:
90// entry/src/main/ets/process/DemoProcess.ets
91import { ChildProcess } from '@kit.AbilityKit';
92
93export default class DemoProcess extends ChildProcess {
94  onStart() {
95    console.log("DemoProcess OnStart() called");
96  }
97}
98```
99
100<!--code_no_check-->
101```ts
102// 使用childProcessManager.startChildProcess方法启动子进程:
103// entry/src/main/ets/tool/Tool.ets
104import { childProcessManager } from '@kit.AbilityKit';
105import { BusinessError } from '@kit.BasicServicesKit';
106import DemoProcess from '../process/DemoProcess';
107
108try {
109  DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉
110  childProcessManager.startChildProcess("./ets/process/DemoProcess.ets", childProcessManager.StartMode.SELF_FORK)
111    .then((data) => {
112      console.log(`startChildProcess success, pid: ${data}`);
113    }, (err: BusinessError) => {
114      console.error(`startChildProcess error, errorCode: ${err.code}`);
115    })
116} catch (err) {
117  console.error(`startChildProcess error, errorCode: ${(err as BusinessError).code}`);
118}
119```
120
121## childProcessManager.startChildProcess
122
123startChildProcess(srcEntry: string, startMode: StartMode, callback: AsyncCallback&lt;number&gt;): void
124
125启动[ArkTS子进程](../../application-models/ability-terminology.md#arkts子进程),使用callback异步回调。
126
127> **说明:**
128>
129> 调用该接口创建子进程成功会返回子进程pid,然后执行子进程的[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)函数,[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)函数执行完后子进程会自动销毁。
130>
131> 调用该接口创建的子进程不支持异步ArkTS API调用,仅支持同步ArkTS API调用。
132
133**系统能力**:SystemCapability.Ability.AbilityRuntime.Core
134
135**参数:**
136
137  | 参数名 | 类型 | 必填 | 说明 |
138  | -------- | -------- | -------- | -------- |
139  | srcEntry | string | 是 | 子进程源文件路径,只支持源文件放在entry类型的模块中,以src/main为根目录。例如子进程文件在entry模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"./ets/process/DemoProcess.ets"。<br/>另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) |
140  | startMode | [StartMode](#startmode) | 是 | 子进程启动模式。 |
141  | callback | AsyncCallback&lt;number&gt; | 是 | 回调函数。当子进程启动成功,err为undefined,data为获取到的子进程pid;否则为错误对象。 |
142
143**错误码**:
144
145  以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)和[元能力子系统错误码](errorcode-ability.md)。
146
147| 错误码ID | 错误信息 |
148| ------- | -------- |
149| 401 | Parameter error. Possible causes: 1.Mandatory parameters are left unspecified; 2.Incorrect parameter types; 3.Parameter verification failed. |
150| 16000050 | Internal error. |
151| 16000061  | Operation not supported. |
152| 16000062  | The number of child processes exceeds the upper limit. |
153
154**示例:**
155
156```ts
157// 在entry模块的src/main/ets/process下创建DemoProcess.ets子进程类:
158// entry/src/main/ets/process/DemoProcess.ets
159import { ChildProcess } from '@kit.AbilityKit';
160
161export default class DemoProcess extends ChildProcess {
162  onStart() {
163    console.log("DemoProcess OnStart() called");
164  }
165}
166```
167
168<!--code_no_check-->
169```ts
170// 使用childProcessManager.startChildProcess方法启动子进程:
171// entry/src/main/ets/tool/Tool.ets
172import { childProcessManager } from '@kit.AbilityKit';
173import { BusinessError } from '@kit.BasicServicesKit';
174import DemoProcess from '../process/DemoProcess';
175
176try {
177  DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉
178  childProcessManager.startChildProcess("./ets/process/DemoProcess.ets", childProcessManager.StartMode.SELF_FORK, (err, data) => {
179    if (data) {
180      console.log(`startChildProcess success, pid: ${data}`);
181    } else {
182      console.error(`startChildProcess error, errorCode: ${err.code}`);
183    }
184  });
185} catch (err) {
186  console.error(`startChildProcess error, errorCode: ${(err as BusinessError).code}`);
187}
188```
189
190## childProcessManager.startArkChildProcess<sup>12+</sup>
191
192startArkChildProcess(srcEntry: string, args: ChildProcessArgs, options?: ChildProcessOptions): Promise&lt;number&gt;
193
194启动[ArkTS子进程](../../application-models/ability-terminology.md#arkts子进程),使用Promise异步回调。
195
196
197> **说明:**
198>
199> 调用该接口创建的子进程不会继承父进程资源,子进程创建成功会返回子进程pid,然后执行子进程的[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)函数。[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)函数执行完后子进程不会自动销毁,需要子进程调用[process.abort](../apis-arkts/js-apis-process.md#processabort)销毁。调用该接口的进程销毁后,所创建的子进程也会一并销毁。
200
201
202**系统能力**:SystemCapability.Ability.AbilityRuntime.Core
203
204**参数:**
205
206  | 参数名 | 类型 | 必填 | 说明 |
207  | -------- | -------- | -------- | -------- |
208  | srcEntry | string | 是 | 子进程源文件路径,不支持源文件放在HAR类型的模块中。由“模块名” + “/” + “文件路径”组成,文件路径以src/main为根目录。例如子进程文件在module1模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"module1/ets/process/DemoProcess.ets"。<br/>另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) |
209  | args | [ChildProcessArgs](js-apis-app-ability-childProcessArgs.md) | 是 | 传递到子进程的参数。 |
210  | options | [ChildProcessOptions](js-apis-app-ability-childProcessOptions.md) | 否 | 子进程的启动配置选项。|
211
212**返回值:**
213
214  | 类型 | 说明 |
215  | -------- | -------- |
216  | Promise&lt;number&gt; | Promise对象,返回子进程pid。 |
217
218**错误码**:
219
220  以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)和[元能力子系统错误码](errorcode-ability.md)。
221
222| 错误码ID | 错误信息 |
223| ------- | -------- |
224| 401 | Parameter error. Possible causes: 1.Mandatory parameters are left unspecified; 2.Incorrect parameter types; 3.Parameter verification failed. |
225| 801 | Capability not supported. |
226| 16000050 | Internal error. |
227| 16000061  | Operation not supported. |
228| 16000062  | The number of child processes exceeds the upper limit. |
229
230**示例:**
231
232子进程部分:
233
234```ts
235// 在module1模块的src/main/ets/process下创建DemoProcess.ets子进程类:
236// module1/src/main/ets/process/DemoProcess.ets
237import { ChildProcess, ChildProcessArgs } from '@kit.AbilityKit';
238
239export default class DemoProcess extends ChildProcess {
240
241  onStart(args?: ChildProcessArgs) {
242    let entryParams = args?.entryParams;
243    let fd = args?.fds?.key1;
244    // ..
245  }
246}
247```
248
249主进程部分,示例中的context的获取方式请参见[获取UIAbility的上下文信息](../../application-models/uiability-usage.md#获取uiability的上下文信息):
250
251<!--code_no_check-->
252```ts
253// 使用childProcessManager.startArkChildProcess方法启动子进程:
254// module1/src/main/ets/tool/Tool.ets
255import { common, ChildProcessArgs, ChildProcessOptions, childProcessManager } from '@kit.AbilityKit';
256import { fileIo } from '@kit.CoreFileKit';
257import { BusinessError } from '@kit.BasicServicesKit';
258import DemoProcess from '../process/DemoProcess';
259
260@Entry
261@Component
262struct Index {
263  build() {
264    Row() {
265      Column() {
266        Text('Click')
267          .fontSize(30)
268          .fontWeight(FontWeight.Bold)
269          .onClick(() => {
270            try {
271              DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉
272              let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
273              let path = context.filesDir + "/test.txt";
274              let file = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY | fileIo.OpenMode.CREATE);
275              let args: ChildProcessArgs = {
276                entryParams: "testParam",
277                fds: {
278                  "key1": file.fd
279                }
280              };
281              let options: ChildProcessOptions = {
282                isolationMode: false
283              };
284              childProcessManager.startArkChildProcess("module1/ets/process/DemoProcess.ets", args, options)
285                .then((pid) => {
286                  console.info(`startChildProcess success, pid: ${pid}`);
287                })
288                .catch((err: BusinessError) => {
289                  console.error(`startChildProcess business error, errorCode: ${err.code}, errorMsg:${err.message}`);
290                })
291            } catch (err) {
292              console.error(`startChildProcess error, errorCode: ${err.code}, errorMsg:${err.message}`);
293            }
294          });
295      }
296      .width('100%')
297    }
298    .height('100%')
299  }
300}
301```
302
303## childProcessManager.startNativeChildProcess<sup>13+</sup>
304
305startNativeChildProcess(entryPoint: string, args: ChildProcessArgs, options?: ChildProcessOptions): Promise&lt;number&gt;
306
307启动[Native子进程](../../application-models/ability-terminology.md#native子进程),使用Promise异步回调。
308
309> **说明:**
310>
311> 调用该接口创建的子进程不会继承父进程资源,子进程创建成功会返回子进程pid,然后加载参数中指定的动态链接库文件并执行子进程的入口函数,入口函数执行完后子进程会自动销毁。调用该接口的进程销毁后,所创建的子进程也会一并销毁。
312
313**系统能力**:SystemCapability.Ability.AbilityRuntime.Core
314
315**参数:**
316
317  | 参数名 | 类型 | 必填 | 说明 |
318  | -------- | -------- | -------- | -------- |
319  | entryPoint | string | 是 | 子进程中调用动态库的符号和入口函数,中间用“:”隔开(例如“libentry.so:Main”)。 |
320  | args | [ChildProcessArgs](js-apis-app-ability-childProcessArgs.md) | 是 | 传递到子进程的参数。 |
321  | options | [ChildProcessOptions](js-apis-app-ability-childProcessOptions.md) | 否 | 子进程的启动配置选项。|
322
323**返回值:**
324
325  | 类型 | 说明 |
326  | -------- | -------- |
327  | Promise&lt;number&gt; | Promise对象,返回子进程pid。 |
328
329**错误码**:
330
331  以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)和[元能力子系统错误码](errorcode-ability.md)。
332
333| 错误码ID | 错误信息 |
334| ------- | -------- |
335| 401 | Parameter error. Possible causes: 1.Mandatory parameters are left unspecified; 2.Incorrect parameter types; 3.Parameter verification failed. |
336| 801 | Capability not supported. Failed to call the API due to limited device capabilities. |
337| 16000050 | Internal error. |
338| 16000061  | Operation not supported. |
339| 16000062  | The number of child processes exceeds the upper limit. |
340
341**示例:**
342
343子进程部分,详见[Native子进程开发指导(C/C++)- 创建支持参数传递的Native子进程](../../application-models/capi_nativechildprocess_development_guideline.md#创建支持参数传递的native子进程):
344
345```c++
346#include <AbilityKit/native_child_process.h>
347
348extern "C" {
349
350/**
351 * 子进程的入口函数,实现子进程的业务逻辑
352 * 函数名称可以自定义,在主进程调用OH_Ability_StartNativeChildProcess方法时指定,此示例中为Main
353 * 函数返回后子进程退出
354 */
355void Main(NativeChildProcess_Args args)
356{
357    // 获取传入的entryPrams
358    char *entryParams = args.entryParams;
359    // 获取传入的fd列表,对应ChildProcessArgs中的args.fds
360    NativeChildProcess_Fd *current = args.fdList.head;
361    while (current != nullptr) {
362        char *fdName = current->fdName;
363        int32_t fd = current->fd;
364        current = current->next;
365        // 业务逻辑..
366    }
367}
368} // extern "C"
369```
370
371主进程部分,示例中的context的获取方式请参见[获取UIAbility的上下文信息](../../application-models/uiability-usage.md#获取uiability的上下文信息):
372
373```ts
374// 主进程:
375// 使用childProcessManager.startNativeChildProcess方法启动子进程:
376import { common, ChildProcessArgs, ChildProcessOptions, childProcessManager } from '@kit.AbilityKit';
377import { fileIo } from '@kit.CoreFileKit';
378import { BusinessError } from '@kit.BasicServicesKit';
379
380@Entry
381@Component
382struct Index {
383  build() {
384    Row() {
385      Column() {
386        Text('Click')
387          .fontSize(30)
388          .fontWeight(FontWeight.Bold)
389          .onClick(() => {
390            try {
391              let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
392              let path = context.filesDir + "/test.txt";
393              let file = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY | fileIo.OpenMode.CREATE);
394              let args: ChildProcessArgs = {
395                entryParams: "testParam",
396                fds: {
397                  "key1": file.fd
398                }
399              };
400              let options: ChildProcessOptions = {
401                isolationMode: false
402              };
403              childProcessManager.startNativeChildProcess("libentry.so:Main", args, options)
404                .then((pid) => {
405                  console.info(`startChildProcess success, pid: ${pid}`);
406                })
407                .catch((err: BusinessError) => {
408                  console.error(`startChildProcess business error, errorCode: ${err.code}, errorMsg:${err.message}`);
409                })
410            } catch (err) {
411              console.error(`startChildProcess error, errorCode: ${err.code}, errorMsg:${err.message}`);
412            }
413          });
414      }
415      .width('100%')
416    }
417    .height('100%')
418  }
419}
420```