智能客服
你问我答,随时在线为你解决问题

























IPC/RPC提供了订阅远端Stub对象状态的机制。当远端Stub对象死亡时,可以自动触发本端Proxy注册的死亡通知。这种死亡通知订阅需要调用指定接口registerDeathRecipient完成。不再需要订阅时,也需要调用指定接口unregisterDeathRecipient取消订阅。
使用这种订阅机制的用户需要继承死亡通知类DeathRecipient,并实现onRemoteDied方法清理资源。该方法会在远端Stub对象所在进程退出或当前RPC通信依赖的软总线连接断开时被回调。
IPC/RPC的订阅机制适用于以下场景:
当Proxy感知到Stub端死亡后,应该清理本地Proxy对象以及相关资源。
RPC不支持匿名Stub对象(没有向SAMgr注册)的死亡通知,IPC支持匿名Stub对象的死亡通知。
此文档中的示例代码描述的是系统应用跨进程通信。
使用场景约束:客户端是第三方/系统应用,服务端是系统应用/服务
| 接口名 | 返回值类型 | 功能描述 |
|---|---|---|
| registerDeathRecipient | void | 注册用于接收远程对象死亡通知的回调,该方法应该在proxy侧调用。 |
| unregisterDeathRecipient | void | 注销用于接收远程对象死亡通知的回调。 |
| onRemoteDied | void | Proxy侧注册死亡通知成功后,当远端Stub对象所在进程死亡时,将自动回调本方法。 |
在IPC(同设备的跨进程通信)场景中,示例代码如下:
导入相关依赖,并定义所需的变量;
- import { BusinessError } from '@kit.BasicServicesKit';
- import { Want, common } from '@kit.AbilityKit';
- import { rpc } from '@kit.IPCKit';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- import { PromptAction } from '@kit.ArkUI';
- import { JSON } from '@kit.ArkTS';
-
- let proxy: rpc.IRemoteObject | undefined;
- let connectId: number | undefined;
-
- // 死亡通知
- class MyDeathRecipient implements rpc.DeathRecipient {
- onRemoteDied() {
- hilog.info(0x0000, 'testTag', 'server is dead');
- }
- }
- let deathRecipient = new MyDeathRecipient();
连接服务,获取代理对象,然后注册死亡监听。在断开连接时,移除死亡监听。
- // 连接服务
- function connectAbility(context:common.UIAbilityContext, promptAction: PromptAction) {
- hilog.info(0x00000, 'testTag', 'begin to connect Ability');
- let want: Want = {
- bundleName: 'com.example.ipc_stub',
- abilityName: 'ServiceAbility',
- };
- let connect: common.ConnectOptions = {
- onConnect: (elementName, remoteProxy) => {
- hilog.info(0x00000, 'testTag', 'onConnect. elementName is :' + JSON.stringify(elementName));
- proxy = remoteProxy;
- // 客户端注册死亡监听
- try {
- proxy.registerDeathRecipient(deathRecipient, 0);
- hilog.info(0x00000, 'testTag', 'registerDeathRecipient success');
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'register failed, code is ' + code + ', message is ' + message);
- }
- // ...
- },
-
- onDisconnect: (elementName) => {
- hilog.info(0x0000, 'testTag', 'onDisconnect. elementName is ' + JSON.stringify(elementName));
- // 客户端移除死亡监听
- try {
- proxy?.unregisterDeathRecipient(deathRecipient, 0);
- hilog.info(0x00000, 'testTag', 'unregisterDeathRecipient success');
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'unregister failed, code is ' + code + ', message is ' + message);
- }
- proxy = undefined;
- // ...
- },
-
- onFailed: (code: number) => {
- hilog.info(0x0000, 'testTag', 'onFailed. code is ' + code);
- // ...
- },
- }
-
- try {
- connectId = context.connectServiceExtensionAbility(want, connect);
- hilog.info(0x00000, 'testTag', 'begin to connect Ability end');
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'connectAbility failed, code is ' + code + ', message is ' + message);
- }
- }
-
- // 断开连接
- function disconnectAbility(context: common.UIAbilityContext) {
- hilog.info(0x00000, 'testTag', 'begin to disconnect Ability. connectId is ' + connectId);
- if (connectId != undefined) {
- try {
- context.disconnectServiceExtensionAbility(connectId);
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'disconnect failed, code is ' + code + ', message is ' + message);
- }
- }
- }
在RPC(跨设备的跨进程通信)场景中,示例代码如下:
导入相关依赖,并定义所需的变量;
- import { BusinessError } from '@kit.BasicServicesKit';
- import { rpc } from '@kit.IPCKit';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- import { distributedDeviceManager } from '@kit.DistributedServiceKit';
- import { abilityAccessCtrl, PermissionRequestResult, common, Want} from '@kit.AbilityKit';
- import { JSON } from '@kit.ArkTS';
- import { PromptAction } from '@kit.ArkUI';
-
- let proxy: rpc.IRemoteObject | undefined;
- let connectId: number | undefined;
- let dmInstance: distributedDeviceManager.DeviceManager;
- let deviceList: Array<distributedDeviceManager.DeviceBasicInfo> | undefined;
- let deviceId: string| undefined;
-
- // 死亡通知
- class MyDeathRecipient implements rpc.DeathRecipient {
- onRemoteDied() {
- hilog.info(0x0000, 'testTag', 'server is dead');
- }
- };
- let deathRecipient = new MyDeathRecipient();
获取允许多设备协同的权限,在组网的情况下获取到对端的设备ID(组网场景下对应设备的唯一网络标识符,可以使用distributedDeviceManager获取目标设备的NetworkId)后连接服务,获取代理对象并注册死亡监听。当代理对象与服务端的通信结束后,在断开连接时,移除死亡监听。
- // 获取权限
- function getPermission(context:common.UIAbilityContext) {
- hilog.info(0x00000, 'testTag', 'begin to requestPermissions');
- try {
- let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
- atManager.requestPermissionsFromUser(context, ['ohos.permission.DISTRIBUTED_DATASYNC'],
- (err: BusinessError, data: PermissionRequestResult) => {
- if (err) {
- hilog.error(0x0000, 'testTag', 'requestPermissions failed, code is ' + err.code);
- hilog.error(0x0000, 'testTag', 'requestPermissions failed, message is ' + err.message);
- } else {
- hilog.info(0x0000, 'testTag', 'requestPermissions success, result is ' + JSON.stringify(data));
- hilog.info(0x0000, 'testTag', 'data permissions is ' + data.permissions);
- hilog.info(0x0000, 'testTag', 'data authResults is ' + data.authResults);
- hilog.info(0x0000, 'testTag', 'data dialogShownResults is ' + data.dialogShownResults);
- }
- });
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'getPermission failed, code is ' + code + ', message is ' + message);
- }
- }
-
- // 获取对端设备信息
- function getDeviceId(promptAction: PromptAction) {
- hilog.info(0x00000, 'testTag', 'begin to getDeviceId');
- try {
- dmInstance = distributedDeviceManager.createDeviceManager('com.example.rpc_client');
- hilog.info(0x0000, 'testTag', 'createDeviceManager success');
- deviceList = dmInstance.getAvailableDeviceListSync();
- hilog.info(0x0000, 'testTag', 'deviceList is ' + JSON.stringify(deviceList));
- if (deviceList.length !== 0) {
- deviceId = deviceList[0].networkId;
- hilog.info(0x0000, 'testTag', 'networkId is ' + deviceId);
- // ...
- }
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'getDeviceId failed, code is ' + code + ', message is ' + message);
- // ...
- }
- }
-
- // 连接服务
- function connectAbility(context:common.UIAbilityContext, promptAction: PromptAction) {
- hilog.info(0x00000, 'testTag', 'begin to connect Ability');
- let want: Want = {
- bundleName: 'com.example.rpc_stub',
- abilityName: 'ServiceAbility',
- deviceId: deviceId,
- }
-
- let connect: common.ConnectOptions = {
- onConnect: (elementName, remoteProxy) => {
- hilog.info(0x00000, 'testTag', 'onConnect. elementName is ' + JSON.stringify(elementName));
- proxy = remoteProxy;
- // 客户端注册死亡监听
- try {
- proxy.registerDeathRecipient(deathRecipient, 0);
- hilog.info(0x00000, 'testTag', 'registerDeathRecipient success');
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'register failed, code is ' + code + ', message is ' + message);
- };
- // ...
- },
- onDisconnect: (elementName) => {
- hilog.info(0x0000, 'testTag', 'onDisconnect. elementName is ' + JSON.stringify(elementName));
- // 客户端移除死亡监听
- try {
- proxy?.unregisterDeathRecipient(deathRecipient, 0);
- hilog.info(0x00000, 'testTag', 'unregisterDeathRecipient success');
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'unregister failed, code is ' + code + ', message is ' + message);
- }
- proxy = undefined;
- // ...
- },
- onFailed: (code: number) => {
- hilog.info(0x0000, 'testTag', 'onFailed. code is ' + code);
- // ...
- },
- }
-
- try {
- connectId = context.connectServiceExtensionAbility(want, connect);
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'connectService failed, code is ' + code + ', message is ' + message);
- }
- }
-
- // 断开连接
- function disconnectAbility(context: common.UIAbilityContext) {
- hilog.info(0x00000, 'testTag', 'begin to disconnect Ability');
- if (connectId != undefined) {
- try {
- context.disconnectServiceExtensionAbility(connectId);
- } catch (err) {
- let code = (err as BusinessError).code;
- let message = (err as BusinessError).message;
- hilog.error(0x0000, 'testTag', 'disconnectService failed, code is ' + code + ', message is ' + message);
- }
- }
- }
正向的死亡通知是Proxy感知Stub的状态,要实现反向的死亡通知(即Stub感知Proxy的状态),可以利用反向死亡通知。例如,进程A(原Stub所在进程)和进程B(原Proxy所在进程),进程B获取到进程A的原Proxy对象后,在B进程新建一个匿名Stub对象(未向SAMgr注册),称为回调Stub,通过sendMessageRequest接口将回调Stub传给进程A的原Stub,进程A就可以获取到进程B的回调Proxy。只要向回调Proxy注册了死亡通知,当进程B(回调Stub)死亡或者RPC通信依赖的软总线连接断开时,回调Proxy会感知并通知进程A(原Stub),从而实现反向死亡通知。
智能客服
你问我答,随时在线为你解决问题
合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
解决方案
精准高效的一站式服务支持,助力开发者商业成功