diff --git a/zh-cn/application-dev/application-models/Readme-CN.md b/zh-cn/application-dev/application-models/Readme-CN.md index ae943323632ca425adb228e350b10ffde60bec4b..e1bb3b2e39c4fe0aac89d10c3528c1174a26e148 100644 --- a/zh-cn/application-dev/application-models/Readme-CN.md +++ b/zh-cn/application-dev/application-models/Readme-CN.md @@ -150,6 +150,3 @@ - [window接口切换](window-switch.md) - [Storage接口切换](storage-switch.md) -- Native子进程开发指导 - - [创建Native子进程](capi_nativechildprocess_development_guideline.md) - - [获取Native子进程退出信息](capi-nativechildprocess-exit-info.md) diff --git a/zh-cn/application-dev/application-models/capi-nativechildprocess-exit-info.md b/zh-cn/application-dev/application-models/capi-nativechildprocess-exit-info.md deleted file mode 100644 index 73f5bf5a9d75c7d486c1ca73792a19e0ff497235..0000000000000000000000000000000000000000 --- a/zh-cn/application-dev/application-models/capi-nativechildprocess-exit-info.md +++ /dev/null @@ -1,69 +0,0 @@ -# 获取Native子进程退出信息 - -## 场景介绍 - -从API version 20开始,支持父进程通过注册回调函数监听子进程,获取子进程异常退出信息,以便父进程做后续优化处理。这里支持监听的子进程必须为[OH_Ability_StartNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_startnativechildprocess)或[startNativeChildProcess](../reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md#childprocessmanagerstartnativechildprocess13)接口创建的子进程。 - -## 接口说明 - -| 名称 | 描述 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| [Ability_NativeChildProcess_ErrCode](../reference/apis-ability-kit/c-apis-ability-childprocess.md#ability_nativechildprocess_errcode) [OH_Ability_RegisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_registernativechildprocessexitcallback) ([OH_Ability_OnNativeChildProcessExit](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_onnativechildprocessexit) onProcessExit) | 注册子进程退出回调函数。 | -| [Ability_NativeChildProcess_ErrCode](../reference/apis-ability-kit/c-apis-ability-childprocess.md#ability_nativechildprocess_errcode) [OH_Ability_UnregisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_unregisternativechildprocessexitcallback) ([OH_Ability_OnNativeChildProcessExit](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_onnativechildprocessexit) onProcessExit) | 解注册子进程退出回调函数。 | - -## 开发步骤 - - -**动态库文件** - -```txt -libchild_process.so -``` - -**头文件** - -```c++ -#include -``` - -1. 主进程-注册和解注册Native子进程异常退出回调。 - - 调用[OH_Ability_RegisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_registernativechildprocessexitcallback)注册Native子进程,如果返回值为NCP_NO_ERROR表示注册成功。 - 调用[OH_Ability_UnregisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_unregisternativechildprocessexitcallback)解注册Native子进程,如果返回值为NCP_NO_ERROR表示解注册成功。 - - ```c++ - #include - void OnNativeChildProcessExit(int32_t pid, int32_t signal) { - OH_LOG_INFO("pid: %{public}d, signal: %{public}d", pid, signal); - } - - void RegisterNativeChildProcessExitCallback() - { - Ability_NativeChildProcess_ErrCode ret = OH_Ability_RegisterNativeChildProcessExitCallback(OnNativeChildProcessExit); - if (ret != NCP_NO_ERROR) { - OH_LOG_ERROR("register failed."); - } - } - - void UnregisterNativeChildProcessExitCallback() - { - Ability_NativeChildProcess_ErrCode ret = OH_Ability_UnregisterNativeChildProcessExitCallback(OnNativeChildProcessExit); - if (ret != NCP_NO_ERROR) { - OH_LOG_ERROR("unregister failed."); - } - } - ``` - -2. 主进程-添加编译依赖项。 - - 修改CMaklist.txt添加必要的依赖库,假设主进程所在的so名称为libmainprocesssample.so(主进程和子进程的实现也可以选择编译到同一个动态库文件)。 - - ```txt - target_link_libraries(mainprocesssample PUBLIC - # 添加依赖的元能力动态库 -     libchild_process.so -     -     # 其它依赖的动态库 -     # ... - ) - ``` diff --git a/zh-cn/application-dev/application-models/capi_nativechildprocess_development_guideline.md b/zh-cn/application-dev/application-models/childprocess_development_guideline.md similarity index 44% rename from zh-cn/application-dev/application-models/capi_nativechildprocess_development_guideline.md rename to zh-cn/application-dev/application-models/childprocess_development_guideline.md index 0e7f74bd06d21e31b8b88810af3b869ef9bcd88a..b029e485951672b9823dd0cf6f9e619103dd2bf8 100644 --- a/zh-cn/application-dev/application-models/capi_nativechildprocess_development_guideline.md +++ b/zh-cn/application-dev/application-models/childprocess_development_guideline.md @@ -1,30 +1,199 @@ -# 创建Native子进程(C/C++) +# 子进程开发指导 -本模块提供了两种创建子进程的方式,开发者可根据需要进行选择。 -- [创建支持IPC回调的子进程](#创建支持ipc回调的子进程):创建子进程,并在父子进程间建立IPC通道,适用于父子进程需要IPC通信的场景。对[IPCKit](../ipc/ipc-capi-development-guideline.md)存在依赖。 -- [创建支持参数传递的子进程](#创建支持参数传递的子进程):创建子进程,并传递字符串和fd句柄参数到子进程。适用于需要传递参数到子进程的场景。 +本模块提供了四种启动子进程的方式,开发者可根据需要进行选择。 +- [启动Ark子进程(无消息循环)](#启动ark子进程无消息循环):启动无消息循环的Ark子进程,不支持传参。子进程中会创建Ark运行时环境,但是不会创建消息循环,不支持异步ArkTS API调用,onStart方法执行完后子进程会自动销毁。推荐使用下面的启动Ark子进程(有消息循环)替代。 + > **说明:** + > 子进程源文件仅支持定义在entry模块。 + > 子进程没有ApplicationContext,不支持依赖ApplicationContext的API调用。 -## 创建支持IPC回调的子进程 +- [启动Ark子进程(有消息循环)](#启动ark子进程有消息循环):启动有消息循环的Ark子进程,并传递字符串和fd句柄参数到子进程。子进程中会创建Ark运行时环境,并创建消息循环,支持异步ArkTS API调用,onStart方法执行完后子进程不会自动销毁。适用于需要在子进程中执行ArkTS代码并传递参数到子进程的场景。 + > **说明:** + > 子进程源文件不支持定义在HAR模块中。 + > 子进程没有ApplicationContext,不支持依赖ApplicationContext的API调用。 + +- [启动支持IPC回调的Native子进程](#启动支持ipc回调的native子进程):启动Native子进程,并在父子进程间建立IPC通道。子进程中不会创建Ark运行时环境。适用于需要在子进程中执行Native代码并且父子进程需要IPC通信的场景。对[IPCKit](../ipc/ipc-capi-development-guideline.md)存在依赖。 +- [启动支持参数传递的Native子进程](#启动支持参数传递的native子进程):启动Native子进程,并传递字符串和fd句柄参数到子进程。子进程中不会创建Ark运行时环境。适用于需要在子进程中执行Native代码并传递参数到子进程的场景。 + +## 启动Ark子进程(无消息循环) + +### 场景介绍 + +本章节介绍如何启动无消息循环的Ark子进程。 + +### 接口说明 + +| 名称 | 描述 | +| ----------- | ----------- | +| [startChildProcess](../reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md#childprocessmanagerstartchildprocess)(srcEntry: string, startMode: [StartMode](../reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md#startmode)): Promise<number> | 启动子进程,并调用子进程的入口方法。使用Promise异步回调。 | + +### 开发步骤 + +1. 子进程-实现onStart回调方法。 + + 在entry模块下创建子进程文件,路径为entry/src/main/ets/process/DemoProcess.ets,并实现onStart回调方法。 + + ```ts + import { ChildProcess } from '@kit.AbilityKit'; + + export default class DemoProcess extends ChildProcess { + + onStart() { + console.log("DemoProcess onStart called."); + // 业务逻辑.. + // onStart执行完后子进程自动销毁 + } + } + ``` + +2. 主进程-调用startChildProcess接口,启动子进程。 + + 在entry/src/main/ets/page/Index.ets文件中调用startChildProcess接口,传入srcEntry和startMode参数启动子进程。
**注意**:需要调用下子DemoProcess的任意方法(例如DemoProcess.toString()方法),防止DemoProcess.ets没有被引用到而被构建工具优化掉。 + + ```ts + import { childProcessManager } from '@kit.AbilityKit'; + import { BusinessError } from '@kit.BasicServicesKit'; + import DemoProcess from '../process/DemoProcess'; + + @Entry + @Component + struct Index { + build() { + Row() { + Column() { + Text('StartChildProcess') + .fontSize(30) + .fontWeight(FontWeight.Bold) + .onClick(() => { + try { + DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉 + // 启动子进程,文件路径以src/main为根目录,必须以“./”开头 + childProcessManager.startChildProcess("./ets/process/DemoProcess.ets", childProcessManager.StartMode.APP_SPAWN_FORK) + .then((pid) => { + console.log(`startChildProcess success, pid: ${pid}`); + }) + .catch((err: BusinessError) => { + console.error(`startChildProcess business error, errorCode: ${err.code}, errorMsg:${err.message}`); + }) + } catch (err) { + console.error(`startChildProcess error, errorCode: ${err.code}, errorMsg:${err.message}`); + } + }); + } + .width('100%') + } + .height('100%') + } + } + ``` + +## 启动Ark子进程(有消息循环) ### 场景介绍 -本章节介绍如何在主进程中创建Native子进程,并在父子进程间建立IPC通道,方便开发者在Native层进行多进程编程。 +本章节介绍如何启动有消息循环的Ark子进程,并传递参数到子进程。 + +### 接口说明 + +| 名称 | 描述 | +| ----------- | ----------- | +| [startArkChildProcess](../reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md#childprocessmanagerstartarkchildprocess12)(srcEntry: string, args: [ChildProcessArgs](../reference/apis-ability-kit/js-apis-app-ability-childProcessArgs.md), options?: [ChildProcessOptions](../reference/apis-ability-kit/js-apis-app-ability-childProcessOptions.md)): Promise<number> | 启动子进程,并调用子进程的入口方法。使用Promise异步回调。 | + +### 开发步骤 + +1. 子进程-实现onStart回调方法。 + + 在entry模块下创建子进程文件,路径为entry/src/main/ets/process/DemoProcess.ets,并实现onStart回调方法。 + + ```ts + import { ChildProcess, ChildProcessArgs } from '@kit.AbilityKit'; + + export default class DemoProcess extends ChildProcess { + + onStart(args?: ChildProcessArgs) { + // 获取传入的entryPrams + let entryParams = args?.entryParams; + // 获取传入的fds + let fd = args?.fds?.key1; + // 业务逻辑.. + // onStart执行完后子进程不自动销毁,可以调用process.abort手动销毁 + } + } + ``` + +2. 主进程-调用startArkChildProcess接口,启动子进程。 + + 在entry/src/main/ets/page/Index.ets文件中调用startArkChildProcess接口,传入srcEntry、args、options等参数,启动子进程。
**注意**:需要调用下子DemoProcess的任意方法(例如DemoProcess.toString()方法),防止DemoProcess.ets没有被引用到而被构建工具优化掉。 + + ```ts + import { common, ChildProcessArgs, ChildProcessOptions, childProcessManager } from '@kit.AbilityKit'; + import { fileIo } from '@kit.CoreFileKit'; + import { BusinessError } from '@kit.BasicServicesKit'; + import DemoProcess from '../process/DemoProcess'; + + @Entry + @Component + struct Index { + build() { + Row() { + Column() { + Text('StartArkChildProcess') + .fontSize(30) + .fontWeight(FontWeight.Bold) + .onClick(() => { + try { + DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉 + let context = this.getUIContext().getHostContext() as common.UIAbilityContext; + let path = context.filesDir + "/test.txt"; + let file = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY | fileIo.OpenMode.CREATE); + let args: ChildProcessArgs = { + entryParams: "testParam", + fds: { + "key1": file.fd + } + }; + let options: ChildProcessOptions = { + isolationMode: false + }; + // 启动子进程,其中参数srcEntry由“模块名” + “/” + “文件路径”组成,文件路径以src/main为根目录,此处不需要写src/main。 + childProcessManager.startArkChildProcess("entry/ets/process/DemoProcess.ets", args, options) + .then((pid) => { + console.info(`startChildProcess success, pid: ${pid}`); + }) + .catch((err: BusinessError) => { + console.error(`startChildProcess business error, errorCode: ${err.code}, errorMsg:${err.message}`); + }) + } catch (err) { + console.error(`startChildProcess error, errorCode: ${err.code}, errorMsg:${err.message}`); + } + }); + } + .width('100%') + } + .height('100%') + } + } + ``` + +## 启动支持IPC回调的Native子进程 + +### 场景介绍 + +本章节介绍如何启动Native子进程,并在父子进程间建立IPC通道,方便开发者在Native层进行多进程编程。 ### 接口说明 | 名称 | 描述 | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| int [OH_Ability_CreateNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_createnativechildprocess) (const char *libName, [OH_Ability_OnNativeChildProcessStarted](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_onnativechildprocessstarted) onProcessStarted) | 创建子进程并加载参数中指定的动态链接库文件,进程启动结果通过回调参数异步通知,需注意回调通知为独立线程,回调函数实现需要注意线程同步,且不能执行高耗时操作避免长时间阻塞。 | +| int [OH_Ability_CreateNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_createnativechildprocess) (const char *libName, [OH_Ability_OnNativeChildProcessStarted](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_onnativechildprocessstarted) onProcessStarted) | 启动子进程并加载参数中指定的动态链接库文件,进程启动结果通过回调参数异步通知,需注意回调通知为独立线程,回调函数实现需要注意线程同步,且不能执行高耗时操作避免长时间阻塞。 | > **说明:** > -> 当前仅支持2in1设备。 -> 从API version 15开始,单个进程最多支持启动50个Native子进程。API version 14及之前版本,单个进程只能启动1个Native子进程。 +> 从API version 15开始,单个进程最多支持启动50个支持IPC回调的Native子进程。API version 14及之前版本,单个进程只能启动1个支持IPC回调的Native子进程。 ### 开发步骤 -基于已创建完成的Native应用开发工程,在此基础上介绍如何使用`AbilityKit`提供的C API接口,创建Native子进程,并同时在父子进程间建立IPC通道。 +基于已创建完成的Native应用开发工程,在此基础上介绍如何使用`AbilityKit`提供的C API接口,启动Native子进程,并同时在父子进程间建立IPC通道。 **动态库文件** @@ -44,7 +213,7 @@ libchild_process.so 在子进程中,实现必要的两个函数**NativeChildProcess_OnConnect**及**NativeChildProcess_MainProc**并导出(假设代码所在的文件名为ChildProcessSample.cpp)。其中NativeChildProcess_OnConnect方法返回的OHIPCRemoteStub对象负责主进程进行IPC通信,具体实现方法请参考[IPC通信开发指导(C/C++)](../ipc/ipc-capi-development-guideline.md),本文不再赘述。 - 子进程启动后会先调用NativeChildProcess_OnConnect获取IPC Stub对象,之后再调用NativeChildProcess_MainProc移交主线程控制权,该函数返回后子进程随即退出。 + 子进程启动后会先调用NativeChildProcess_OnConnect获取IPC Stub对象,之后再调用NativeChildProcess_MainProc移交主线程控制权。NativeChildProcess_MainProc函数返回后子进程随即退出。 ```c++ #include @@ -55,7 +224,8 @@ libchild_process.so { // ipcRemoteStub指向子进程实现的ipc stub对象,用于接收来自主进程的IPC消息并响应 // 子进程根据业务逻辑控制其生命周期 -     return ipcRemoteStub; + // g_ipcStubObj实现参考“IPC通信开发指导” +     return g_ipcStubObj.GetRemoteStub(); } void NativeChildProcess_MainProc() @@ -114,7 +284,7 @@ libchild_process.so 4. 主进程-启动Native子进程。 - 调用API启动Native子进程,需要注意返回值为NCP_NO_ERROR仅代表成功调用native子进程启动逻辑,实际的启动结果通过第二个参数中指定的回调函数异步通知。需注意**仅允许在主进程中创建子进程**。 + 调用API启动Native子进程,需要注意返回值为NCP_NO_ERROR仅代表成功调用native子进程启动逻辑,实际的启动结果通过第二个参数中指定的回调函数异步通知。需注意**仅允许在主进程中启动子进程**。 ```c++ #include @@ -142,20 +312,22 @@ libchild_process.so ) ``` -## 创建支持参数传递的子进程 +## 启动支持参数传递的Native子进程 ### 场景介绍 -本章节介绍如何创建Native子进程,并传递参数到子进程。 +本章节介绍如何启动Native子进程,并传递参数到子进程。目前支持NDK接口和ArkTs接口两种方式启动Native子进程,开发者可按需选择。 ### 接口说明 | 名称 | 描述 | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| [Ability_NativeChildProcess_ErrCode](../reference/apis-ability-kit/c-apis-ability-childprocess.md#ability_nativechildprocess_errcode) [OH_Ability_StartNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_startnativechildprocess) (const char \*entry, [NativeChildProcess_Args](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_args) args, [NativeChildProcess_Options](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_options) options, int32_t *pid) | 启动子进程并返回子进程pid。 | +| [Ability_NativeChildProcess_ErrCode](../reference/apis-ability-kit/c-apis-ability-childprocess.md#ability_nativechildprocess_errcode) [OH_Ability_StartNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_startnativechildprocess) (const char \*entry, [NativeChildProcess_Args](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_args) args, [NativeChildProcess_Options](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_options) options, int32_t *pid) | NDK接口,启动Native子进程,加载参数中指定的动态链接库文件并调用入口函数。使用Promise异步回调。 | +| [startNativeChildProcess](../reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md#childprocessmanagerstartnativechildprocess13)(entryPoint: string, args: [ChildProcessArgs](../reference/apis-ability-kit/js-apis-app-ability-childProcessArgs.md), options?: [ChildProcessOptions](../reference/apis-ability-kit/js-apis-app-ability-childProcessOptions.md)): Promise<number> | ArkTS接口,启动Native子进程,加载参数中指定的动态链接库文件并调用入口函数。使用Promise异步回调。 | ### 开发步骤 +基于已创建完成的Native应用开发工程,在此基础上介绍如何使用`AbilityKit`提供的ArkTS接口和NDK接口启动Native子进程。 **动态库文件** @@ -223,7 +395,9 @@ libchild_process.so 3. 主进程-启动Native子进程。 - 调用API启动Native子进程,返回值为NCP_NO_ERROR代表成功启动native子进程。 + (1) 通过NDK接口: + + 调用OH_Ability_StartNativeChildProcess接口启动子进程(假设代码所在的文件名为MainProcessSample.cpp)。需要注意返回值为NCP_NO_ERROR仅代表成功调用Native子进程启动逻辑,实际的启动结果以子进程的入口函数Main是否成功调用为准。 ```c++ #include @@ -270,11 +444,17 @@ libchild_process.so } ``` -4. 主进程-添加编译依赖项。 - 修改CMaklist.txt添加必要的依赖库,假设主进程所在的so名称为libmainprocesssample.so(主进程和子进程的实现也可以选择编译到同一个动态库文件)。 ```txt + add_library(mainprocesssample SHARED + # 主进程源文件 + MainProcessSample.cpp + + # 其它代码源文件 + # ... + ) + target_link_libraries(mainprocesssample PUBLIC # 添加依赖的元能力动态库     libchild_process.so @@ -284,6 +464,59 @@ libchild_process.so ) ``` + (2)通过ArkTS接口: + + 调用childProcessManager.startNativeChildProcess启动子进程。需要注意接口返回成功仅代表成功调用Native子进程启动逻辑,实际的启动结果以子进程的入口函数Main是否成功调用为准。 + + ```ts + import { common, ChildProcessArgs, ChildProcessOptions, childProcessManager } from '@kit.AbilityKit'; + import { fileIo } from '@kit.CoreFileKit'; + import { BusinessError } from '@kit.BasicServicesKit'; + + @Entry + @Component + struct Index { + build() { + Row() { + Column() { + Text('Click') + .fontSize(30) + .fontWeight(FontWeight.Bold) + .onClick(() => { + try { + let context = this.getUIContext().getHostContext() as common.UIAbilityContext; + let path = context.filesDir + "/test.txt"; + let file = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY | fileIo.OpenMode.CREATE); + // 设置entryParam和fds,如不需要可省略 + let args: ChildProcessArgs = { + entryParams: "testParam", + fds: { + "fd1": file.fd + } + }; + let options: ChildProcessOptions = { + isolationMode: false + }; + // 第一个参数"libchildprocesssample.so:Main"为实现了子进程Main方法的动态库文件名称和入口方法名 + childProcessManager.startNativeChildProcess("libchildprocesssample.so:Main", args, options) + .then((pid) => { + console.info(`startChildProcess success, pid: ${pid}`); + }) + .catch((err: BusinessError) => { + console.error(`startChildProcess business error, errorCode: ${err.code}, errorMsg:${err.message}`); + }) + } catch (err) { + console.error(`startChildProcess error, errorCode: ${err.code}, errorMsg:${err.message}`); + } + }); + } + .width('100%') + } + .height('100%') + } + } + ``` + ## 子进程获取启动参数 ### 场景介绍 @@ -313,7 +546,7 @@ libchild_process.so **获取启动参数** -[OH_Ability_StartNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_startnativechildprocess)创建子进程后,子进程内的任意so和任意子线程可以通过调用[OH_Ability_GetCurrentChildProcessArgs](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_getcurrentchildprocessargs)()获取到子进程的启动参数[NativeChildProcess_Args](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_args),便于操作相关的文件描述符。 +[OH_Ability_StartNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_startnativechildprocess)启动子进程后,子进程内的任意so和任意子线程可以通过调用[OH_Ability_GetCurrentChildProcessArgs](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_getcurrentchildprocessargs)()获取到子进程的启动参数[NativeChildProcess_Args](../reference/apis-ability-kit/c-apis-ability-childprocess.md#nativechildprocess_args),便于操作相关的文件描述符。 ```c++ #include @@ -356,3 +589,72 @@ void Main(NativeChildProcess_Args args) } // extern "C" ``` +## 获取Native子进程退出信息 + +### 场景介绍 + +从API version 20开始,支持父进程通过注册回调函数监听子进程,获取子进程退出信息,以便父进程做后续优化处理。这里支持监听的子进程必须为[OH_Ability_StartNativeChildProcess](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_startnativechildprocess)或[startNativeChildProcess](../reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md#childprocessmanagerstartnativechildprocess13)接口启动的子进程。 + +### 接口说明 + +| 名称 | 描述 | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| [Ability_NativeChildProcess_ErrCode](../reference/apis-ability-kit/c-apis-ability-childprocess.md#ability_nativechildprocess_errcode) [OH_Ability_RegisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_registernativechildprocessexitcallback) ([OH_Ability_OnNativeChildProcessExit](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_onnativechildprocessexit) onProcessExit) | 注册子进程退出回调函数。 | +| [Ability_NativeChildProcess_ErrCode](../reference/apis-ability-kit/c-apis-ability-childprocess.md#ability_nativechildprocess_errcode) [OH_Ability_UnregisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_unregisternativechildprocessexitcallback) ([OH_Ability_OnNativeChildProcessExit](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_onnativechildprocessexit) onProcessExit) | 解注册子进程退出回调函数。 | + +### 开发步骤 + + +**动态库文件** + +```txt +libchild_process.so +``` + +**头文件** + +```c++ +#include +``` + +1. 主进程-注册和解注册Native子进程退出回调。 + + 调用[OH_Ability_RegisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_registernativechildprocessexitcallback)注册Native子进程退出回调,如果返回值为NCP_NO_ERROR表示注册成功。 + 调用[OH_Ability_UnregisterNativeChildProcessExitCallback](../reference/apis-ability-kit/c-apis-ability-childprocess.md#oh_ability_unregisternativechildprocessexitcallback)解注册Native子进程退出回调,如果返回值为NCP_NO_ERROR表示解注册成功。 + + ```c++ + #include + void OnNativeChildProcessExit(int32_t pid, int32_t signal) { + // Native子进程退出回调 + } + + void RegisterNativeChildProcessExitCallback() + { + Ability_NativeChildProcess_ErrCode ret = OH_Ability_RegisterNativeChildProcessExitCallback(OnNativeChildProcessExit); + if (ret != NCP_NO_ERROR) { + // 注册失败异常处理 + } + } + + void UnregisterNativeChildProcessExitCallback() + { + Ability_NativeChildProcess_ErrCode ret = OH_Ability_UnregisterNativeChildProcessExitCallback(OnNativeChildProcessExit); + if (ret != NCP_NO_ERROR) { + // 解注册失败异常处理 + } + } + ``` + +2. 主进程-添加编译依赖项。 + + 修改CMaklist.txt添加必要的依赖库,假设主进程所在的so名称为libmainprocesssample.so(主进程和子进程的实现也可以选择编译到同一个动态库文件)。 + + ```txt + target_link_libraries(mainprocesssample PUBLIC + # 添加依赖的元能力动态库 +     libchild_process.so +     +     # 其它依赖的动态库 +     # ... + ) + ``` diff --git a/zh-cn/application-dev/ipc/ipc-capi-development-guideline.md b/zh-cn/application-dev/ipc/ipc-capi-development-guideline.md index 2be81da2d829a12f43ce0dba823e55351c2b9b72..37fa405b136748c465d98e94f739eff2d7640e03 100644 --- a/zh-cn/application-dev/ipc/ipc-capi-development-guideline.md +++ b/zh-cn/application-dev/ipc/ipc-capi-development-guideline.md @@ -9,7 +9,7 @@ IPC CAPI接口不直接提供获取通信代理对象的能力,该功能由[Ab ![图](./figures/_i_p_c_architecture_diagram.png) -进程间IPC通道的建立,请参考[Native子进程开发指导(C/C++)](../application-models/capi_nativechildprocess_development_guideline.md)。本文重点介绍IPC CAPI的使用。 +进程间IPC通道的建立,请参考[启动支持IPC回调的Native子进程](../application-models/childprocess_development_guideline.md#启动支持ipc回调的native子进程)。本文重点介绍IPC CAPI的使用。 ## 接口说明 diff --git a/zh-cn/application-dev/reference/apis-ability-kit/c-apis-ability-childprocess.md b/zh-cn/application-dev/reference/apis-ability-kit/c-apis-ability-childprocess.md index 7ad08efd301577fe6b1f66f0c7af0130d5a9980d..adf3cab452f1674293b75ed888e484b368461882 100644 --- a/zh-cn/application-dev/reference/apis-ability-kit/c-apis-ability-childprocess.md +++ b/zh-cn/application-dev/reference/apis-ability-kit/c-apis-ability-childprocess.md @@ -5,7 +5,7 @@ 提供子进程的管理能力,支持创建Native子进程并在父子进程间建立IPC通道,用于实现多进程应用开发。 -创建的子进程不支持UI界面,也不支持Context相关的接口调用。通过此模块和[childProcessManager](js-apis-app-ability-childProcessManager.md)(非SELF_FORK模式)启动的子进程总数最大为512个。 +创建的子进程不支持UI界面,也不支持Context相关的接口调用。通过此模块和[childProcessManager](js-apis-app-ability-childProcessManager.md)(非SELF_FORK模式)单个应用启动的子进程总数最大为512个(系统资源充足情况下)。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core @@ -102,7 +102,7 @@ typedef void (*OH_Ability_OnNativeChildProcessExit)(int32_t pid, int32_t signal) | 名称 | 描述 | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | pid | 子进程的pid。 | -| signal | 子进程的异常退出信号。 | +| signal | 子进程的退出信号。 | **参见:** @@ -319,7 +319,7 @@ Ability_NativeChildProcess_ErrCode OH_Ability_StartNativeChildProcess( 启动Native子进程,加载参数中指定的动态链接库文件并调用入口函数。支持传参到子进程。子进程中不支持创建ArkTS基础运行时环境。 -参数所指定的动态库必须实现参数为[NativeChildProcess_Args](#nativechildprocess_args)入口函数并导出。详见[Native子进程开发指导(C/C++)- 创建支持参数传递的子进程](../../application-models/capi_nativechildprocess_development_guideline.md#创建支持参数传递的子进程)。 +参数所指定的动态库必须实现参数为[NativeChildProcess_Args](#nativechildprocess_args)入口函数并导出。详见[启动支持参数传递的Native子进程](../../application-models/childprocess_development_guideline.md#启动支持参数传递的native子进程)。 > **说明:** > @@ -370,9 +370,9 @@ Ability_NativeChildProcess_ErrCode OH_Ability_RegisterNativeChildProcessExitCall **描述**: -注册Native子进程异常退出回调函数,当通过[OH_Ability_StartNativeChildProcess](#oh_ability_startnativechildprocess)和[@ohos.app.ability.childProcessManager的startNativeChildProcess](js-apis-app-ability-childProcessManager.md#childprocessmanagerstartnativechildprocess13)启动的子进程异常退出时,调用入口参数的回调函数。当重复注册同一个回调函数时,子进程退出时只会执行一次回调函数。 +注册Native子进程退出回调函数,当通过[OH_Ability_StartNativeChildProcess](#oh_ability_startnativechildprocess)和[@ohos.app.ability.childProcessManager的startNativeChildProcess](js-apis-app-ability-childProcessManager.md#childprocessmanagerstartnativechildprocess13)启动的子进程退出时,调用入口参数的回调函数。当重复注册同一个回调函数时,子进程退出时只会执行一次回调函数。 -参数必须实现[OH_Ability_OnNativeChildProcessExit](#oh_ability_onnativechildprocessexit)入口函数。详见[注册Native子进程退出回调](../../application-models/capi-nativechildprocess-exit-info.md)。 +参数必须实现[OH_Ability_OnNativeChildProcessExit](#oh_ability_onnativechildprocessexit)入口函数。详见[获取Native子进程退出信息](../../application-models/childprocess_development_guideline.md#获取native子进程退出信息)。 **起始版本**:20 @@ -395,9 +395,9 @@ Ability_NativeChildProcess_ErrCode OH_Ability_UnregisterNativeChildProcessExitCa **描述**: -解注册Native子进程异常退出回调函数。 +解注册Native子进程退出回调函数。 -参数必须实现[OH_Ability_OnNativeChildProcessExit](#oh_ability_onnativechildprocessexit)入口函数。详见[解注册Native子进程退出回调](../../application-models/capi-nativechildprocess-exit-info.md)。 +参数必须实现[OH_Ability_OnNativeChildProcessExit](#oh_ability_onnativechildprocessexit)入口函数。详见[获取Native子进程退出信息](../../application-models/childprocess_development_guideline.md#获取native子进程退出信息)。 **起始版本**:20 diff --git a/zh-cn/application-dev/reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md b/zh-cn/application-dev/reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md index 7a417fa15b8293ae1d672f3fb4f706333edddac7..070f6dbbf4f27b05e0e2cb55c2563895774d7a5a 100644 --- a/zh-cn/application-dev/reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md +++ b/zh-cn/application-dev/reference/apis-ability-kit/js-apis-app-ability-childProcessManager.md @@ -2,7 +2,7 @@ childProcessManager模块提供子进程管理能力,支持子进程启动操作。当前仅支持2in1、tablet设备。 -创建的子进程不支持UI界面,也不支持Context相关的接口调用。通过此模块(非SELF_FORK模式)和[ChildProcess](c-apis-ability-childprocess.md)启动的子进程总数最大为512个。 +创建的子进程不支持UI界面,也不支持Context相关的接口调用。通过此模块(非SELF_FORK模式)和[ChildProcess](c-apis-ability-childprocess.md)单个应用启动的子进程总数最大为512个(系统资源充足情况下)。 > **说明:** > @@ -24,7 +24,7 @@ import { childProcessManager } from '@kit.AbilityKit'; | 名称 | 值 | 说明 | | -------- | ----------------- | ----------------- | -| SELF_FORK | 0 | 从App自身进程Fork子进程。以该模式启动的子进程中不能进行Binder IPC调用,会导致子进程Crash。不支持异步ArkTS API调用。 | +| SELF_FORK | 0 | 从App自身进程Fork子进程。以该模式启动的子进程中不能进行Binder IPC调用,会导致子进程Crash。 | | APP_SPAWN_FORK | 1 | 从AppSpawn Fork子进程。以该模式启动的子进程不会继承父进程资源,且没有ApplicationContext,子进程中不支持依赖ApplicationContext的API调用。 | ## childProcessManager.startChildProcess @@ -33,7 +33,7 @@ startChildProcess(srcEntry: string, startMode: StartMode): Promise<number> 启动子进程,并调用子进程的入口方法。使用Promise异步回调。 -创建子进程成功会返回子进程pid,但并不代表入口方法调用成功,具体结果以[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)方法是否调用成功为准。子进程中不支持再次创建子进程。 +创建子进程成功会返回子进程pid,但并不代表入口方法调用成功,具体结果以[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)方法是否调用成功为准。子进程中不支持再次创建子进程,且不支持异步ArkTS API调用。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core @@ -41,7 +41,7 @@ startChildProcess(srcEntry: string, startMode: StartMode): Promise<number> | 参数名 | 类型 | 必填 | 说明 | | -------- | -------- | -------- | -------- | - | srcEntry | string | 是 | 子进程源文件路径,只支持源文件放在entry类型的模块中,以src/main为根目录。例如子进程文件在entry模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"./ets/process/DemoProcess.ets"。
另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) | + | srcEntry | string | 是 | 子进程源文件路径,只支持源文件放在entry类型的模块中,以src/main为根目录,必须以“./”开头。例如子进程文件在entry模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"./ets/process/DemoProcess.ets"。
另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) | | startMode | [StartMode](#startmode) | 是 | 子进程启动模式。 | **返回值:** @@ -85,7 +85,7 @@ import DemoProcess from '../process/DemoProcess'; try { DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉 - childProcessManager.startChildProcess("./ets/process/DemoProcess.ets", childProcessManager.StartMode.SELF_FORK) + childProcessManager.startChildProcess("./ets/process/DemoProcess.ets", childProcessManager.StartMode.APP_SPAWN_FORK) .then((data) => { console.log(`startChildProcess success, pid: ${data}`); }, (err: BusinessError) => { @@ -102,7 +102,7 @@ startChildProcess(srcEntry: string, startMode: StartMode, callback: AsyncCallbac 启动子进程,并调用子进程的入口方法。使用callback异步回调。 -创建子进程成功会返回子进程pid,但并不代表入口方法调用成功,具体结果以[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)方法是否调用成功为准。子进程中不支持再次创建子进程。 +创建子进程成功会返回子进程pid,但并不代表入口方法调用成功,具体结果以[ChildProcess.onStart](js-apis-app-ability-childProcess.md#childprocessonstart)方法是否调用成功为准。子进程中不支持再次创建子进程,且不支持异步ArkTS API调用。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core @@ -110,7 +110,7 @@ startChildProcess(srcEntry: string, startMode: StartMode, callback: AsyncCallbac | 参数名 | 类型 | 必填 | 说明 | | -------- | -------- | -------- | -------- | - | srcEntry | string | 是 | 子进程源文件路径,只支持源文件放在entry类型的模块中,以src/main为根目录。例如子进程文件在entry模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"./ets/process/DemoProcess.ets"。
另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) | + | srcEntry | string | 是 | 子进程源文件路径,只支持源文件放在entry类型的模块中,以src/main为根目录,必须以“./”开头。例如子进程文件在entry模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"./ets/process/DemoProcess.ets"。
另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) | | startMode | [StartMode](#startmode) | 是 | 子进程启动模式。 | | callback | AsyncCallback<number> | 是 | 回调函数。当子进程启动成功,err为undefined,data为获取到的子进程pid;否则为错误对象。 | @@ -149,7 +149,7 @@ import DemoProcess from '../process/DemoProcess'; try { DemoProcess.toString(); // 这里要调用下DemoProcess类的任意方法,防止没有引用到而被构建工具优化掉 - childProcessManager.startChildProcess("./ets/process/DemoProcess.ets", childProcessManager.StartMode.SELF_FORK, (err, data) => { + childProcessManager.startChildProcess("./ets/process/DemoProcess.ets", childProcessManager.StartMode.APP_SPAWN_FORK, (err, data) => { if (data) { console.log(`startChildProcess success, pid: ${data}`); } else { @@ -177,7 +177,7 @@ startArkChildProcess(srcEntry: string, args: ChildProcessArgs, options?: ChildPr | 参数名 | 类型 | 必填 | 说明 | | -------- | -------- | -------- | -------- | - | srcEntry | string | 是 | 子进程源文件路径,不支持源文件放在HAR类型的模块中。由“模块名” + “/” + “文件路径”组成,文件路径以src/main为根目录。例如子进程文件在module1模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"module1/./ets/process/DemoProcess.ets"。
另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) | + | srcEntry | string | 是 | 子进程源文件路径,不支持源文件放在HAR类型的模块中。由“模块名” + “/” + “文件路径”组成,文件路径以src/main为根目录。例如子进程文件在module1模块下src/main/ets/process/DemoProcess.ets,则srcEntry为"module1/ets/process/DemoProcess.ets"。
另外,需要确保子进程源文件被其它文件引用到,防止被构建工具优化掉。(详见下方示例代码) | | args | [ChildProcessArgs](js-apis-app-ability-childProcessArgs.md) | 是 | 传递到子进程的参数。 | | options | [ChildProcessOptions](js-apis-app-ability-childProcessOptions.md) | 否 | 子进程的启动配置选项。| @@ -211,7 +211,9 @@ import { ChildProcess, ChildProcessArgs } from '@kit.AbilityKit'; export default class DemoProcess extends ChildProcess { onStart(args?: ChildProcessArgs) { + // 获取传入的entryPrams let entryParams = args?.entryParams; + // 获取传入的fds let fd = args?.fds?.key1; // .. } @@ -253,7 +255,7 @@ struct Index { let options: ChildProcessOptions = { isolationMode: false }; - childProcessManager.startArkChildProcess("module1/./ets/process/DemoProcess.ets", args, options) + childProcessManager.startArkChildProcess("module1/ets/process/DemoProcess.ets", args, options) .then((pid) => { console.info(`startChildProcess success, pid: ${pid}`); }) @@ -312,7 +314,7 @@ startNativeChildProcess(entryPoint: string, args: ChildProcessArgs, options?: Ch **示例:** -子进程部分,详见[Native子进程开发指导(C/C++)- 创建支持参数传递的子进程](../../application-models/capi_nativechildprocess_development_guideline.md#创建支持参数传递的子进程): +子进程部分,详见[启动支持参数传递的Native子进程](../../application-models/childprocess_development_guideline.md#启动支持参数传递的native子进程): ```c++ #include diff --git a/zh-cn/application-dev/reference/apis-ability-kit/native__child__process_8h.md b/zh-cn/application-dev/reference/apis-ability-kit/native__child__process_8h.md index 21282fc47497b4cb68459be0a158878310a365ce..4f8c38d75ccf38611179965b8e688e6669e486dc 100644 --- a/zh-cn/application-dev/reference/apis-ability-kit/native__child__process_8h.md +++ b/zh-cn/application-dev/reference/apis-ability-kit/native__child__process_8h.md @@ -3,7 +3,7 @@ ## 概述 -支持创建Native子进程,并在父子进程间建立IPC通道。通过此模块和[childProcessManager](js-apis-app-ability-childProcessManager.md)(非SELF_FORK模式)可以启动的子进程总数最大为512个。 +支持创建Native子进程,并在父子进程间建立IPC通道。通过此模块和[childProcessManager](js-apis-app-ability-childProcessManager.md)(非SELF_FORK模式)单个应用可以启动的子进程总数最大为512个(系统资源充足情况下)。 **库**:libchild_process.so diff --git a/zh-cn/application-dev/website.md b/zh-cn/application-dev/website.md index 15c6f2cda3de6fd2c70f94e204a974685776dca6..182de09901249942173ec7bcb01612b6abb0b0bb 100644 --- a/zh-cn/application-dev/website.md +++ b/zh-cn/application-dev/website.md @@ -199,9 +199,6 @@ - [window接口切换](application-models/window-switch.md) - [Storage接口切换](application-models/storage-switch.md) - - Native子进程开发指导 - - [创建Native子进程](application-models/capi_nativechildprocess_development_guideline.md) - - [获取Native子进程退出信息](application-models/capi-nativechildprocess-exit-info.md) - ArkData(方舟数据管理) - [ArkData简介](database/data-mgmt-overview.md) - 标准化数据定义