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