• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 { fileIo } from '@kit.CoreFileKit';
229import { BusinessError } from '@kit.BasicServicesKit';
230import DemoProcess from '../process/DemoProcess';
231
232@Entry
233@Component
234struct Index {
235  build() {
236    Row() {
237      Column() {
238        Text('Click')
239          .fontSize(30)
240          .fontWeight(FontWeight.Bold)
241          .onClick(() => {
242            try {
243              DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉
244              let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
245              let path = context.filesDir + "/test.txt";
246              let file = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY | fileIo.OpenMode.CREATE);
247              let args: ChildProcessArgs = {
248                entryParams: "testParam",
249                fds: {
250                  "key1": file.fd
251                }
252              };
253              let options: ChildProcessOptions = {
254                isolationMode: false
255              };
256              childProcessManager.startArkChildProcess("module1/./ets/process/DemoProcess.ets", args, options)
257                .then((pid) => {
258                  console.info(`startChildProcess success, pid: ${pid}`);
259                })
260                .catch((err: BusinessError) => {
261                  console.error(`startChildProcess business error, errorCode: ${err.code}, errorMsg:${err.message}`);
262                })
263            } catch (err) {
264              console.error(`startChildProcess error, errorCode: ${err.code}, errorMsg:${err.message}`);
265            }
266          });
267      }
268      .width('100%')
269    }
270    .height('100%')
271  }
272}
273```
274
275## childProcessManager.startNativeChildProcess<sup>13+</sup>
276
277startNativeChildProcess(entryPoint: string, args: ChildProcessArgs, options?: ChildProcessOptions): Promise&lt;number&gt;
278
279启动Native子进程,加载参数中指定的动态链接库文件并调用入口函数。使用Promise异步回调。
280
281子进程不会继承父进程资源。创建子进程成功会返回子进程pid,但并不代表入口函数调用成功,具体结果以子进程的入口函数是否调用成功为准。子进程中不支持再次创建子进程,且不支持创建ArkTS基础运行时环境。
282
283入口函数执行完后子进程会自动销毁。主进程销毁后子进程也会一并销毁。
284
285**系统能力**:SystemCapability.Ability.AbilityRuntime.Core
286
287**参数:**
288
289  | 参数名 | 类型 | 必填 | 说明 |
290  | -------- | -------- | -------- | -------- |
291  | entryPoint | string | 是 | 子进程中调用动态库的符号和入口函数,中间用“:”隔开(例如“libentry.so:Main”)。 |
292  | args | [ChildProcessArgs](js-apis-app-ability-childProcessArgs.md) | 是 | 传递到子进程的参数。 |
293  | options | [ChildProcessOptions](js-apis-app-ability-childProcessOptions.md) | 否 | 子进程的启动配置选项。|
294
295**返回值:**
296
297  | 类型 | 说明 |
298  | -------- | -------- |
299  | Promise&lt;number&gt; | Promise对象,返回子进程pid。 |
300
301**错误码**:
302
303  以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)和[元能力子系统错误码](errorcode-ability.md)。
304
305| 错误码ID | 错误信息 |
306| ------- | -------- |
307| 401 | Parameter error. Possible causes: 1.Mandatory parameters are left unspecified; 2.Incorrect parameter types; 3.Parameter verification failed. |
308| 801 | Capability not supported. Failed to call the API due to limited device capabilities. |
309| 16000050 | Internal error. |
310| 16000061  | Operation not supported. The API cannot be called in a child process. |
311| 16000062  | The number of child processes exceeds the upper limit. |
312
313**示例:**
314
315子进程部分,详见[Native子进程开发指导(C/C++)- 创建支持参数传递的子进程](../../application-models/capi_nativechildprocess_development_guideline.md#创建支持参数传递的子进程):
316
317```c++
318#include <AbilityKit/native_child_process.h>
319
320extern "C" {
321
322/**
323 * 子进程的入口函数,实现子进程的业务逻辑
324 * 函数名称可以自定义,在主进程调用OH_Ability_StartNativeChildProcess方法时指定,此示例中为Main
325 * 函数返回后子进程退出
326 */
327void Main(NativeChildProcess_Args args)
328{
329    // 获取传入的entryPrams
330    char *entryParams = args.entryParams;
331    // 获取传入的fd列表,对应ChildProcessArgs中的args.fds
332    NativeChildProcess_Fd *current = args.fdList.head;
333    while (current != nullptr) {
334        char *fdName = current->fdName;
335        int32_t fd = current->fd;
336        current = current->next;
337        // 业务逻辑..
338    }
339}
340} // extern "C"
341```
342
343主进程部分,示例中的context的获取方式请参见[获取UIAbility的上下文信息](../../application-models/uiability-usage.md#获取uiability的上下文信息):
344
345```ts
346// 主进程:
347// 使用childProcessManager.startNativeChildProcess方法启动子进程:
348import { common, ChildProcessArgs, ChildProcessOptions, childProcessManager } from '@kit.AbilityKit';
349import { fileIo } from '@kit.CoreFileKit';
350import { BusinessError } from '@kit.BasicServicesKit';
351
352@Entry
353@Component
354struct Index {
355  build() {
356    Row() {
357      Column() {
358        Text('Click')
359          .fontSize(30)
360          .fontWeight(FontWeight.Bold)
361          .onClick(() => {
362            try {
363              let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
364              let path = context.filesDir + "/test.txt";
365              let file = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY | fileIo.OpenMode.CREATE);
366              let args: ChildProcessArgs = {
367                entryParams: "testParam",
368                fds: {
369                  "key1": file.fd
370                }
371              };
372              let options: ChildProcessOptions = {
373                isolationMode: false
374              };
375              childProcessManager.startNativeChildProcess("libentry.so:Main", args, options)
376                .then((pid) => {
377                  console.info(`startChildProcess success, pid: ${pid}`);
378                })
379                .catch((err: BusinessError) => {
380                  console.error(`startChildProcess business error, errorCode: ${err.code}, errorMsg:${err.message}`);
381                })
382            } catch (err) {
383              console.error(`startChildProcess error, errorCode: ${err.code}, errorMsg:${err.message}`);
384            }
385          });
386      }
387      .width('100%')
388    }
389    .height('100%')
390  }
391}
392```