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