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<number> | 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<number>): 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<number> | 是 | 回调函数。当子进程启动成功,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<number> 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<number> | 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<number> 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<number> | 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```