提交 03df37c1 编写于 作者: L l30043718

Description:IPC&RPC communication guidance added

Feature or Bugfix:IPC&RPC communication guidance added
Binary Source: No
Signed-off-by: NLixiaoying25 <lixiaoying25@huawei.com>
上级 a4e1b0f1
...@@ -29,7 +29,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -29,7 +29,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
external_deps = [ external_deps = [
"ipc:ipc_single", "ipc:ipc_single",
] ]
#rpc场景 #rpc场景
external_deps = [ external_deps = [
"ipc:ipc_core", "ipc:ipc_core",
...@@ -50,12 +50,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -50,12 +50,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```c++ ```c++
#include "iremote_broker.h" #include "iremote_broker.h"
//定义消息码 //定义消息码
const int TRANS_ID_PING_ABILITY = 5 const int TRANS_ID_PING_ABILITY = 5;
const std::string DESCRIPTOR = "test.ITestAbility"; const std::string DESCRIPTOR = "test.ITestAbility";
class ITestAbility : public IRemoteBroker { class ITestAbility : public IRemoteBroker {
public: public:
// DECLARE_INTERFACE_DESCRIPTOR是必需的,入参需使用std::u16string; // DECLARE_INTERFACE_DESCRIPTOR是必需的,入参需使用std::u16string;
...@@ -71,13 +71,13 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -71,13 +71,13 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```c++ ```c++
#include "iability_test.h" #include "iability_test.h"
#include "iremote_stub.h" #include "iremote_stub.h"
class TestAbilityStub : public IRemoteStub<ITestAbility> { class TestAbilityStub : public IRemoteStub<ITestAbility> {
public: public:
virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
int TestPingAbility(const std::u16string &dummy) override; int TestPingAbility(const std::u16string &dummy) override;
}; };
int TestAbilityStub::OnRemoteRequest(uint32_t code, int TestAbilityStub::OnRemoteRequest(uint32_t code,
MessageParcel &data, MessageParcel &reply, MessageOption &option) MessageParcel &data, MessageParcel &reply, MessageOption &option)
{ {
...@@ -98,12 +98,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -98,12 +98,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```c++ ```c++
#include "iability_server_test.h" #include "iability_server_test.h"
class TestAbility : public TestAbilityStub { class TestAbility : public TestAbilityStub {
public: public:
int TestPingAbility(const std::u16string &dummy); int TestPingAbility(const std::u16string &dummy);
} }
int TestAbility::TestPingAbility(const std::u16string &dummy) { int TestAbility::TestPingAbility(const std::u16string &dummy) {
return 0; return 0;
} }
...@@ -117,7 +117,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -117,7 +117,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
#include "iability_test.h" #include "iability_test.h"
#include "iremote_proxy.h" #include "iremote_proxy.h"
#include "iremote_object.h" #include "iremote_object.h"
class TestAbilityProxy : public IRemoteProxy<ITestAbility> { class TestAbilityProxy : public IRemoteProxy<ITestAbility> {
public: public:
explicit TestAbilityProxy(const sptr<IRemoteObject> &impl); explicit TestAbilityProxy(const sptr<IRemoteObject> &impl);
...@@ -125,12 +125,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -125,12 +125,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
private: private:
static inline BrokerDelegator<TestAbilityProxy> delegator_; // 方便后续使用iface_cast宏 static inline BrokerDelegator<TestAbilityProxy> delegator_; // 方便后续使用iface_cast宏
} }
TestAbilityProxy::TestAbilityProxy(const sptr<IRemoteObject> &impl) TestAbilityProxy::TestAbilityProxy(const sptr<IRemoteObject> &impl)
: IRemoteProxy<ITestAbility>(impl) : IRemoteProxy<ITestAbility>(impl)
{ {
} }
int TestAbilityProxy::TestPingAbility(const std::u16string &dummy){ int TestAbilityProxy::TestPingAbility(const std::u16string &dummy){
MessageOption option; MessageOption option;
MessageParcel dataParcel, replyParcel; MessageParcel dataParcel, replyParcel;
...@@ -149,7 +149,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -149,7 +149,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
// 注册到本设备内 // 注册到本设备内
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
samgr->AddSystemAbility(saId, new TestAbility()); samgr->AddSystemAbility(saId, new TestAbility());
// 在组网场景下,会被同步到其他设备上 // 在组网场景下,会被同步到其他设备上
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ISystemAbilityManager::SAExtraProp saExtra; ISystemAbilityManager::SAExtraProp saExtra;
...@@ -166,10 +166,10 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -166,10 +166,10 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(saId); sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(saId);
sptr<ITestAbility> testAbility = iface_cast<ITestAbility>(remoteObject); // 使用iface_cast宏转换成具体类型 sptr<ITestAbility> testAbility = iface_cast<ITestAbility>(remoteObject); // 使用iface_cast宏转换成具体类型
// 获取其他设备注册的SA的proxy // 获取其他设备注册的SA的proxy
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
// networkId是组网场景下对应设备的标识符,可以通过GetLocalNodeDeviceInfo获取 // networkId是组网场景下对应设备的标识符,可以通过GetLocalNodeDeviceInfo获取
sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(saId, networkId); sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(saId, networkId);
sptr<TestAbilityProxy> proxy(new TestAbilityProxy(remoteObject)); // 直接构造具体Proxy sptr<TestAbilityProxy> proxy(new TestAbilityProxy(remoteObject)); // 直接构造具体Proxy
...@@ -180,59 +180,97 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -180,59 +180,97 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
1. 添加依赖 1. 添加依赖
```ts ```ts
import rpc from "@ohos.rpc" import rpc from "@ohos.rpc";
import featureAbility from "@ohos.ability.featureAbility" // 仅FA模型需要导入@ohos.ability.featureAbility
// import featureAbility from "@ohos.ability.featureAbility";
``` ```
Stage模型需要获取context
```ts
import Ability from "@ohos.app.ability.UIAbility";
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate");
globalThis.context = this.context;
}
onDestroy() {
console.log("[Demo] MainAbility onDestroy");
}
onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate");
}
onWindowStageDestroy() {
// Main window is destroyed, release UI related resources
console.log("[Demo] MainAbility onWindowStageDestroy");
}
onForeground() {
// Ability has brought to foreground
console.log("[Demo] MainAbility onForeground");
}
onBackground() {
// Ability has back to background
console.log("[Demo] MainAbility onBackground");
}
}
```
2. 绑定Ability 2. 绑定Ability
首先,构造变量want,指定要绑定的Ability所在应用的包名、组件名,如果是跨设备的场景,还需要绑定目标设备NetworkId(组网场景下对应设备的标识符,可以使用deviceManager获取目标设备的NetworkId);然后,构造变量connect,指定绑定成功、绑定失败、断开连接时的回调函数;最后,使用featureAbility提供的接口绑定Ability。 首先,构造变量want,指定要绑定的Ability所在应用的包名、组件名,如果是跨设备的场景,还需要绑定目标设备NetworkId(组网场景下对应设备的标识符,可以使用deviceManager获取目标设备的NetworkId);然后,构造变量connect,指定绑定成功、绑定失败、断开连接时的回调函数;最后,FA模型使用featureAbility提供的接口绑定Ability,Stage模型通过context获取服务后用提供的接口绑定Ability。
```ts ```ts
import rpc from "@ohos.rpc" import rpc from "@ohos.rpc";
import featureAbility from "@ohos.ability.featureAbility" // 仅FA模型需要导入@ohos.ability.featureAbility
// import featureAbility from "@ohos.ability.featureAbility";
let proxy = null
let connectId = null let proxy = null;
let connectId = null;
// 单个设备绑定Ability // 单个设备绑定Ability
let want = { let want = {
// 包名和组件名写实际的值 // 包名和组件名写实际的值
"bundleName": "ohos.rpc.test.server", "bundleName": "ohos.rpc.test.server",
"abilityName": "ohos.rpc.test.server.ServiceAbility", "abilityName": "ohos.rpc.test.server.ServiceAbility",
} };
let connect = { let connect = {
onConnect:function(elementName, remote) { onConnect:function(elementName, remote) {
proxy = remote proxy = remote;
}, },
onDisconnect:function(elementName) { onDisconnect:function(elementName) {
}, },
onFailed:function() { onFailed:function() {
proxy = null proxy = null;
} }
} };
connectId = featureAbility.connectAbility(want, connect) // FA模型使用此方法连接服务
// connectId = featureAbility.connectAbility(want, connect);
connectId = globalThis.context.connectServiceExtensionAbility(want,connect);
// 如果是跨设备绑定,可以使用deviceManager获取目标设备NetworkId // 如果是跨设备绑定,可以使用deviceManager获取目标设备NetworkId
import deviceManager from '@ohos.distributedHardware.deviceManager' import deviceManager from '@ohos.distributedHardware.deviceManager';
function deviceManagerCallback(deviceManager) { function deviceManagerCallback(deviceManager) {
let deviceList = deviceManager.getTrustedDeviceListSync() let deviceList = deviceManager.getTrustedDeviceListSync();
let networkId = deviceList[0].networkId let networkId = deviceList[0].networkId;
let want = { let want = {
"bundleName": "ohos.rpc.test.server", "bundleName": "ohos.rpc.test.server",
"abilityName": "ohos.rpc.test.service.ServiceAbility", "abilityName": "ohos.rpc.test.service.ServiceAbility",
"networkId": networkId, "networkId": networkId,
"flags": 256 "flags": 256
} };
connectId = featureAbility.connectAbility(want, connect) // 建立连接后返回的Id需要保存下来,在断开连接时需要作为参数传入
// FA模型使用此方法连接服务
// connectId = featureAbility.connectAbility(want, connect);
connectId = globalThis.context.connectServiceExtensionAbility(want,connect);
} }
// 第一个参数是本应用的包名,第二个参数是接收deviceManager的回调函数 // 第一个参数是本应用的包名,第二个参数是接收deviceManager的回调函数
deviceManager.createDeviceManager("ohos.rpc.test", deviceManagerCallback) deviceManager.createDeviceManager("ohos.rpc.test", deviceManagerCallback);
``` ```
3. 服务端处理客户端请求 3. 服务端处理客户端请求
...@@ -240,78 +278,80 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -240,78 +278,80 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```ts ```ts
onConnect(want: Want) { onConnect(want: Want) {
var robj:rpc.RemoteObject = new Stub("rpcTestAbility") var robj:rpc.RemoteObject = new Stub("rpcTestAbility");
return robj return robj;
} }
class Stub extends rpc.RemoteObject { class Stub extends rpc.RemoteObject {
constructor(descriptor) { constructor(descriptor) {
super(descriptor) super(descriptor);
} }
onRemoteMessageRequest(code, data, reply, option) { onRemoteMessageRequest(code, data, reply, option) {
// 根据code处理客户端的请求 // 根据code处理客户端的请求
return true return true;
} }
} }
``` ```
4. 客户端处理服务端响应 4. 客户端处理服务端响应
客户端在onConnect回调里接收到代理对象,调用sendRequestAsync方法发起请求,在期约(JavaScript期约:用于表示一个异步操作的最终完成或失败及其结果值)或者回调函数里接收结果。 客户端在onConnect回调里接收到代理对象,调用sendRequest方法发起请求,在期约(JavaScript期约:用于表示一个异步操作的最终完成或失败及其结果值)或者回调函数里接收结果。
```ts ```ts
// 使用期约 // 使用期约
let option = new rpc.MessageOption() let option = new rpc.MessageOption();
let data = rpc.MessageParcel.create() let data = rpc.MessageParcel.create();
let reply = rpc.MessageParcel.create() let reply = rpc.MessageParcel.create();
// 往data里写入参数 // 往data里写入参数
proxy.sendRequestAsync(1, data, reply, option) proxy.sendRequest(1, data, reply, option)
.then(function(result) { .then(function(result) {
if (result.errCode != 0) { if (result.errCode != 0) {
console.error("send request failed, errCode: " + result.errCode) console.error("send request failed, errCode: " + result.errCode);
return return;
} }
// 从result.reply里读取结果 // 从result.reply里读取结果
}) })
.catch(function(e) { .catch(function(e) {
console.error("send request got exception: " + e) console.error("send request got exception: " + e);
} })
.finally(() => { .finally(() => {
data.reclaim() data.reclaim();
reply.reclaim() reply.reclaim();
}) })
// 使用回调函数 // 使用回调函数
function sendRequestCallback(result) { function sendRequestCallback(result) {
try { try {
if (result.errCode != 0) { if (result.errCode != 0) {
console.error("send request failed, errCode: " + result.errCode) console.error("send request failed, errCode: " + result.errCode);
return return;
} }
// 从result.reply里读取结果 // 从result.reply里读取结果
} finally { } finally {
result.data.reclaim() result.data.reclaim();
result.reply.reclaim() result.reply.reclaim();
} }
} }
let option = new rpc.MessageOption() let option = new rpc.MessageOption();
let data = rpc.MessageParcel.create() let data = rpc.MessageParcel.create();
let reply = rpc.MessageParcel.create() let reply = rpc.MessageParcel.create();
// 往data里写入参数 // 往data里写入参数
proxy.sendRequest(1, data, reply, option, sendRequestCallback) proxy.sendRequest(1, data, reply, option, sendRequestCallback);
``` ```
5. 断开连接 5. 断开连接
IPC通信结束后,使用featureAbility的接口断开连接。 IPC通信结束后,FA模型使用featureAbility的接口断开连接,Stage模型在获取context后用提供的接口断开连接。
```ts ```ts
import rpc from "@ohos.rpc" import rpc from "@ohos.rpc";
import featureAbility from "@ohos.ability.featureAbility" // 仅FA模型需要导入@ohos.ability.featureAbility
// import featureAbility from "@ohos.ability.featureAbility";
function disconnectCallback() { function disconnectCallback() {
console.info("disconnect ability done") console.info("disconnect ability done");
} }
featureAbility.disconnectAbility(connectId, disconnectCallback) // FA模型使用此方法断开连接
// featureAbility.disconnectAbility(connectId, disconnectCallback);
globalThis.context.disconnectServiceExtensionAbility(connectId);
``` ```
...@@ -3,35 +3,25 @@ ...@@ -3,35 +3,25 @@
## 基本概念 ## 基本概念
IPC(Inter-Process Communication)与RPC(Remote Procedure Call)用于实现跨进程通信,不同的是前者使用Binder驱动,用于设备内的跨进程通信,后者使用软总线驱动,用于跨设备跨进程通信。需要跨进程通信的原因是因为每个进程都有自己独立的资源和内存空间,其他进程不能随意访问不同进程的内存和资源,IPC/RPC便是为了突破这一点。IPC和RPC通常采用客户端-服务器(Client-Server)模型,在使用时,请求服务的(Client)一端进程可获取提供服务(Server)一端所在进程的代理(Proxy),并通过此代理读写数据来实现进程间的数据通信,更具体的讲,首先请求服务的(Client)一端会建立一个服务提供端(Server)的代理对象,这个代理对象具备和服务提供端(Server)一样的功能,若想访问服务提供端(Server)中的某一个方法,只需访问代理对象中对应的方法即可,代理对象会将请求发送给服务提供端(Server);然后服务提供端(Server)处理接受到的请求,处理完之后通过驱动返回处理结果给代理对象;最后代理对象将请求结果进一步返回给请求服务端(Client)。通常,Server会先注册系统能力(System Ability)到系统能力管理者(System Ability Manager,缩写SAMgr)中,SAMgr负责管理这些SA并向Client提供相关的接口。Client要和某个具体的SA通信,必须先从SAMgr中获取该SA的代理,然后使用代理和SA通信。下文直接使用Proxy表示服务请求方,Stub表示服务提供方。 IPC(Inter-Process Communication)与RPC(Remote Procedure Call)用于实现跨进程通信,不同的是前者使用Binder驱动,用于设备内的跨进程通信,后者使用软总线驱动,用于跨设备跨进程通信。需要跨进程通信的原因是因为每个进程都有自己独立的资源和内存空间,其他进程不能随意访问不同进程的内存和资源,IPC/RPC便是为了突破这一点。
![IPC&RPC通信机制](figures/075sd302-aeb9-481a-bb8f-e552sdb61ead.PNG) > **说明:**
> Stage模型不能直接使用本文介绍的IPC和RPC,需要通过以下能力实现相关业务场景:
>- IPC典型使用场景为[后台服务](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-models/background-services.md),后台服务通过IPC机制提供跨进程的服务调用能力。
## 约束与限制 >- RPC典型使用场景为[多端协同](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/application-models/hop-multi-device-collaboration.md),多端协同通过RPC机制提供远端接口调用与数据传递。
- 单个设备上跨进程通信时,传输的数据量最大约为1MB,过大的数据量请使用[匿名共享内存](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-rpc.md#ashmem8)
- 不支持在RPC中订阅匿名Stub对象(没有向SAMgr注册Stub对象)的死亡通知。
- 不支持把跨设备的Proxy对象传递回该Proxy对象所指向的Stub对象所在的设备,即指向远端设备Stub的Proxy对象不能在本设备内进行二次跨进程传递。
## 使用建议
首先,需要编写接口类,接口类中必须定义消息码,供通信双方标识操作,可以有未实现的的方法,因为通信双方均需继承该接口类且双方不能是抽象类,所以此时定义的未实现的方法必须在双方继承时给出实现,这保证了继承双方不是抽象类。然后,需要编写Stub端相关类及其接口,并且实现AsObject方法及OnRemoteRequest方法。同时,也需要编写Proxy端,实现接口类中的方法和AsObject方法,也可以封装一些额外的方法用于调用SendRequest向对端发送数据。以上三者都具备后,便可以向SAMgr注册SA了,此时的注册应该在Stub所在进程完成。最后,在需要的地方从SAMgr中获取Proxy,便可通过Proxy实现与Stub的跨进程通信了。
相关步骤:
- 实现接口类:需继承IRemoteBroker,需定义消息码,可声明不在此类实现的方法。 ## 实现原理
- 实现服务提供端(Stub):需继承IRemoteStub或者RemoteObject,需重写AsObject方法及OnRemoteRequest方法 IPC和RPC通常采用客户端-服务器(Client-Server)模型,在使用时,请求服务的(Client)一端进程可获取提供服务(Server)一端所在进程的代理(Proxy),并通过此代理读写数据来实现进程间的数据通信,更具体的讲,首先请求服务的(Client)一端会建立一个服务提供端(Server)的代理对象,这个代理对象具备和服务提供端(Server)一样的功能,若想访问服务提供端(Server)中的某一个方法,只需访问代理对象中对应的方法即可,代理对象会将请求发送给服务提供端(Server);然后服务提供端(Server)处理接受到的请求,处理完之后通过驱动返回处理结果给代理对象;最后代理对象将请求结果进一步返回给请求服务端(Client)。通常,Server会先注册系统能力(System Ability)到系统能力管理者(System Ability Manager,缩写SAMgr)中,SAMgr负责管理这些SA并向Client提供相关的接口。Client要和某个具体的SA通信,必须先从SAMgr中获取该SA的代理,然后使用代理和SA通信。下文直接使用Proxy表示服务请求方,Stub表示服务提供方
- 实现服务请求端(Proxy):需继承IRemoteProxy或RemoteProxy,需重写AsObject方法,封装所需方法调用SendRequest。 ![IPC&RPC通信机制](figures/075sd302-aeb9-481a-bb8f-e552sdb61ead.PNG)
- 注册SA:申请SA的唯一ID,向SAMgr注册SA。
- 获取SA:通过SA的ID和设备ID获取Proxy,使用Proxy与远端通信 ## 约束与限制
- 单个设备上跨进程通信时,传输的数据量最大约为1MB,过大的数据量请使用[匿名共享内存](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-rpc.md#ashmem8)
## 相关模块 - 不支持在RPC中订阅匿名Stub对象(没有向SAMgr注册Stub对象)的死亡通知。
[分布式任务调度子系统](https://gitee.com/openharmony/ability_dmsfwk) - 不支持把跨设备的Proxy对象传递回该Proxy对象所指向的Stub对象所在的设备,即指向远端设备Stub的Proxy对象不能在本设备内进行二次跨进程传递。
\ No newline at end of file
# 远端状态订阅开发实例 # 远端状态订阅开发实例
IPC/RPC提供对远端Stub对象状态的订阅机制, 在远端Stub对象消亡时,可触发消亡通知告诉本地Proxy对象。这种状态通知订阅需要调用特定接口完成,当不再需要订阅时也需要调用特定接口取消。使用这种订阅机制的用户,需要实现消亡通知接口DeathRecipient并实现onRemoteDied方法清理资源。该方法会在远端Stub对象所在进程消亡或所在设备离开组网时被回调。值得注意的是,调用这些接口有一定的顺序。首先,需要Proxy订阅Stub消亡通知,若在订阅期间Stub状态正常,则在不再需要时取消订阅;若在订阅期间Stub所在进程退出或者所在设备退出组网,则会自动触发Proxy自定义的后续操作。 IPC/RPC提供对远端Stub对象状态的订阅机制,在远端Stub对象消亡时,可触发消亡通知告诉本地Proxy对象。这种状态通知订阅需要调用特定接口完成,当不再需要订阅时也需要调用特定接口取消。使用这种订阅机制的用户,需要实现消亡通知接口DeathRecipient并实现onRemoteDied方法清理资源。该方法会在远端Stub对象所在进程消亡或所在设备离开组网时被回调。值得注意的是,调用这些接口有一定的顺序。首先,需要Proxy订阅Stub消亡通知,若在订阅期间Stub状态正常,则在不再需要时取消订阅;若在订阅期间Stub所在进程退出或者所在设备退出组网,则会自动触发Proxy自定义的后续操作。
## 使用场景 ## 使用场景
...@@ -21,7 +21,6 @@ IPC/RPC提供对远端Stub对象状态的订阅机制, 在远端Stub对象消 ...@@ -21,7 +21,6 @@ IPC/RPC提供对远端Stub对象状态的订阅机制, 在远端Stub对象消
#include "iremote_broker.h" #include "iremote_broker.h"
#include "iremote_stub.h" #include "iremote_stub.h"
//定义消息码 //定义消息码
enum { enum {
TRANS_ID_PING_ABILITY = 5, TRANS_ID_PING_ABILITY = 5,
...@@ -61,9 +60,6 @@ int TestServiceProxy::TestPingAbility(const std::u16string &dummy){ ...@@ -61,9 +60,6 @@ int TestServiceProxy::TestPingAbility(const std::u16string &dummy){
} }
``` ```
```c++ ```c++
#include "iremote_object.h" #include "iremote_object.h"
...@@ -86,16 +82,52 @@ result = object->RemoveDeathRecipient(deathRecipient); // 移除消亡通知 ...@@ -86,16 +82,52 @@ result = object->RemoveDeathRecipient(deathRecipient); // 移除消亡通知
## JS侧接口 ## JS侧接口
| 接口名 | 返回值类型 | 功能描述 | | 接口名 | 返回值类型 | 功能描述 |
| -------------------- | ---------- | ------------------------------------------------------------ | | ------------------------ | ---------- | ----------------------------------------------------------------- |
| addDeathRecippient | boolean | 注册用于接收远程对象消亡通知的回调,增加proxy对象上的消亡通知。 | | registerDeathRecipient | void | 注册用于接收远程对象消亡通知的回调,增加 proxy 对象上的消亡通知。 |
| removeDeathRecipient | boolean | 注销用于接收远程对象消亡通知的回调。 | | unregisterDeathRecipient | void | 注销用于接收远程对象消亡通知的回调。 |
| onRemoteDied | void | 在成功添加死亡通知订阅后,当远端对象死亡时,将自动调用本方法。 | | onRemoteDied | void | 在成功添加死亡通知订阅后,当远端对象死亡时,将自动调用本方法。 |
### 获取context
Stage模型在连接服务前需要先获取context
```ts
import Ability from "@ohos.app.ability.UIAbility";
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate");
globalThis.context = this.context;
}
onDestroy() {
console.log("[Demo] MainAbility onDestroy");
}
onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate");
}
onWindowStageDestroy() {
// Main window is destroyed, release UI related resources
console.log("[Demo] MainAbility onWindowStageDestroy");
}
onForeground() {
// Ability has brought to foreground
console.log("[Demo] MainAbility onForeground");
}
onBackground() {
// Ability has back to background
console.log("[Demo] MainAbility onBackground");
}
}
```
### 参考代码 ### 参考代码
```ts ```ts
import FA from "@ohos.ability.featureAbility"; // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -113,15 +145,19 @@ let want = { ...@@ -113,15 +145,19 @@ let want = {
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
FA.connectAbility(want, connect); // FA模型通过此方法连接服务
// FA.connectAbility(want, connect);
globalThis.context.connectServiceExtensionAbility(want, connect);
class MyDeathRecipient { class MyDeathRecipient {
onRemoteDied() { onRemoteDied() {
console.log("server died"); console.log("server died");
} }
} }
let deathRecipient = new MyDeathRecipient(); let deathRecipient = new MyDeathRecipient();
proxy.addDeathRecippient(deathRecipient, 0); proxy.registerDeathRecippient(deathRecipient, 0);
proxy.removeDeathRecipient(deathRecipient, 0); proxy.unregisterDeathRecipient(deathRecipient, 0);
``` ```
## Stub感知Proxy消亡(匿名Stub的使用) ## Stub感知Proxy消亡(匿名Stub的使用)
......
...@@ -2396,7 +2396,7 @@ readException(): void ...@@ -2396,7 +2396,7 @@ readException(): void
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -2414,10 +2414,10 @@ readException(): void ...@@ -2414,10 +2414,10 @@ readException(): void
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -4856,9 +4856,9 @@ readException(): void ...@@ -4856,9 +4856,9 @@ readException(): void
Stage模型的应用在获取服务前需要先获取context,具体方法可参考[获取context](#获取context) Stage模型的应用在获取服务前需要先获取context,具体方法可参考[获取context](#获取context)
```ts ```ts
// 仅FA模型需要导入@ohos.ability.;featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -4876,10 +4876,10 @@ readException(): void ...@@ -4876,10 +4876,10 @@ readException(): void
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -5450,6 +5450,7 @@ marshalling(dataOut: MessageSequence): boolean ...@@ -5450,6 +5450,7 @@ marshalling(dataOut: MessageSequence): boolean
| 类型 | 说明 | | 类型 | 说明 |
| ------- | -------------------------------- | | ------- | -------------------------------- |
| boolean | true:封送成功,false:封送失败。| | boolean | true:封送成功,false:封送失败。|
**示例:** **示例:**
```ts ```ts
...@@ -5555,6 +5556,7 @@ marshalling(dataOut: MessageParcel): boolean ...@@ -5555,6 +5556,7 @@ marshalling(dataOut: MessageParcel): boolean
| 类型 | 说明 | | 类型 | 说明 |
| ------- | -------------------------------- | | ------- | -------------------------------- |
| boolean | true:封送成功,false:封送失败。 | | boolean | true:封送成功,false:封送失败。 |
**示例:** **示例:**
```ts ```ts
...@@ -5671,7 +5673,7 @@ asObject(): IRemoteObject ...@@ -5671,7 +5673,7 @@ asObject(): IRemoteObject
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -5689,10 +5691,10 @@ asObject(): IRemoteObject ...@@ -5689,10 +5691,10 @@ asObject(): IRemoteObject
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6115,7 +6117,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me ...@@ -6115,7 +6117,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6133,10 +6135,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me ...@@ -6133,10 +6135,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6191,7 +6193,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence, ...@@ -6191,7 +6193,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6209,10 +6211,10 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence, ...@@ -6209,10 +6211,10 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6275,7 +6277,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me ...@@ -6275,7 +6277,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6293,10 +6295,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me ...@@ -6293,10 +6295,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6352,7 +6354,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence, ...@@ -6352,7 +6354,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6383,10 +6385,10 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence, ...@@ -6383,10 +6385,10 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
result.data.reclaim(); result.data.reclaim();
result.reply.reclaim(); result.reply.reclaim();
} }
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6433,7 +6435,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me ...@@ -6433,7 +6435,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6464,10 +6466,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me ...@@ -6464,10 +6466,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
result.data.reclaim(); result.data.reclaim();
result.reply.reclaim(); result.reply.reclaim();
} }
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6517,7 +6519,7 @@ getLocalInterface(interface: string): IRemoteBroker ...@@ -6517,7 +6519,7 @@ getLocalInterface(interface: string): IRemoteBroker
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6535,10 +6537,10 @@ getLocalInterface(interface: string): IRemoteBroker ...@@ -6535,10 +6537,10 @@ getLocalInterface(interface: string): IRemoteBroker
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6583,7 +6585,7 @@ queryLocalInterface(interface: string): IRemoteBroker ...@@ -6583,7 +6585,7 @@ queryLocalInterface(interface: string): IRemoteBroker
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6601,10 +6603,10 @@ queryLocalInterface(interface: string): IRemoteBroker ...@@ -6601,10 +6603,10 @@ queryLocalInterface(interface: string): IRemoteBroker
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6645,7 +6647,7 @@ registerDeathRecipient(recipient: DeathRecipient, flags: number): void ...@@ -6645,7 +6647,7 @@ registerDeathRecipient(recipient: DeathRecipient, flags: number): void
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6663,10 +6665,10 @@ registerDeathRecipient(recipient: DeathRecipient, flags: number): void ...@@ -6663,10 +6665,10 @@ registerDeathRecipient(recipient: DeathRecipient, flags: number): void
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6717,7 +6719,7 @@ addDeathRecipient(recipient: DeathRecipient, flags: number): boolean ...@@ -6717,7 +6719,7 @@ addDeathRecipient(recipient: DeathRecipient, flags: number): boolean
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6735,10 +6737,10 @@ addDeathRecipient(recipient: DeathRecipient, flags: number): boolean ...@@ -6735,10 +6737,10 @@ addDeathRecipient(recipient: DeathRecipient, flags: number): boolean
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6784,7 +6786,7 @@ unregisterDeathRecipient(recipient: DeathRecipient, flags: number): void ...@@ -6784,7 +6786,7 @@ unregisterDeathRecipient(recipient: DeathRecipient, flags: number): void
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6802,10 +6804,10 @@ unregisterDeathRecipient(recipient: DeathRecipient, flags: number): void ...@@ -6802,10 +6804,10 @@ unregisterDeathRecipient(recipient: DeathRecipient, flags: number): void
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6857,7 +6859,7 @@ removeDeathRecipient(recipient: DeathRecipient, flags: number): boolean ...@@ -6857,7 +6859,7 @@ removeDeathRecipient(recipient: DeathRecipient, flags: number): boolean
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6875,10 +6877,10 @@ removeDeathRecipient(recipient: DeathRecipient, flags: number): boolean ...@@ -6875,10 +6877,10 @@ removeDeathRecipient(recipient: DeathRecipient, flags: number): boolean
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -6925,7 +6927,7 @@ getDescriptor(): string ...@@ -6925,7 +6927,7 @@ getDescriptor(): string
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -6943,10 +6945,10 @@ getDescriptor(): string ...@@ -6943,10 +6945,10 @@ getDescriptor(): string
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
上述onConnect回调函数中的proxy对象需要等ability异步连接成功后才会被赋值,然后才可调用proxy对象的getDescriptor接口方法获取对象的接口描述符 上述onConnect回调函数中的proxy对象需要等ability异步连接成功后才会被赋值,然后才可调用proxy对象的getDescriptor接口方法获取对象的接口描述符
...@@ -6984,7 +6986,7 @@ getInterfaceDescriptor(): string ...@@ -6984,7 +6986,7 @@ getInterfaceDescriptor(): string
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -7002,10 +7004,10 @@ getInterfaceDescriptor(): string ...@@ -7002,10 +7004,10 @@ getInterfaceDescriptor(): string
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -7037,7 +7039,7 @@ isObjectDead(): boolean ...@@ -7037,7 +7039,7 @@ isObjectDead(): boolean
```ts ```ts
// 仅FA模型需要导入@ohos.ability.featureAbility // 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility"; // import FA from "@ohos.ability.featureAbility";
let proxy; let proxy;
let connect = { let connect = {
onConnect: function(elementName, remoteProxy) { onConnect: function(elementName, remoteProxy) {
...@@ -7055,10 +7057,10 @@ isObjectDead(): boolean ...@@ -7055,10 +7057,10 @@ isObjectDead(): boolean
"bundleName": "com.ohos.server", "bundleName": "com.ohos.server",
"abilityName": "com.ohos.server.EntryAbility", "abilityName": "com.ohos.server.EntryAbility",
}; };
// FA模型使用此方法连接服务 // FA模型使用此方法连接服务
// FA.connectAbility(want,connect); // FA.connectAbility(want,connect);
globalThis.context.connectServiceExtensionAbility(want, connect); globalThis.context.connectServiceExtensionAbility(want, connect);
``` ```
...@@ -7093,9 +7095,9 @@ MessageOption构造函数。 ...@@ -7093,9 +7095,9 @@ MessageOption构造函数。
**参数:** **参数:**
| 参数名 | 类型 | 必填 | 说明 | | 参数名 | 类型 | 必填 | 说明 |
| --------- | ------ | ---- | -------------------------------------- | | ------ | ------- | ---- | -------------------------------------- |
| syncFlags | number | 否 | 同步调用或异步调用标志。默认同步调用。 | | async | boolean | 否 | 同步调用或异步调用标志。默认同步调用。 |
**示例:** **示例:**
...@@ -7823,7 +7825,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence, ...@@ -7823,7 +7825,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
| 类型 | 说明 | | 类型 | 说明 |
| ---------------------------- | --------------------------------------------- | | ---------------------------- | --------------------------------------------- |
| Promise&lt;RequestResult&gt; | 返回一个期约,兑现值是sendRequestResult实例。 | | Promise&lt;RequestResult&gt; | 返回一个期约,兑现值是RequestResult实例。 |
**示例:** **示例:**
...@@ -9099,30 +9101,31 @@ readFromAshmem(size: number, offset: number): number[] ...@@ -9099,30 +9101,31 @@ readFromAshmem(size: number, offset: number): number[]
```ts ```ts
import Ability from '@ohos.app.ability.UIAbility'; import Ability from '@ohos.app.ability.UIAbility';
export default class MainAbility extends Ability { export default class MainAbility extends Ability {
onCreate(want, launchParam) { onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate"); console.log("[Demo] MainAbility onCreate");
globalThis.context = this.context; globalThis.context = this.context;
} }
onDestroy() { onDestroy() {
console.log("[Demo] MainAbility onDestroy"); console.log("[Demo] MainAbility onDestroy");
} }
onWindowStageCreate(windowStage) { onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability // Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate"); console.log("[Demo] MainAbility onWindowStageCreate");
} }
onWindowStageDestroy() { onWindowStageDestroy() {
// Main window is destroyed, release UI related resources // Main window is destroyed, release UI related resources
console.log("[Demo] MainAbility onWindowStageDestroy"); console.log("[Demo] MainAbility onWindowStageDestroy");
} }
onForeground() { onForeground() {
// Ability has brought to foreground // Ability has brought to foreground
console.log("[Demo] MainAbility onForeground"); console.log("[Demo] MainAbility onForeground");
} }
onBackground() { onBackground() {
// Ability has back to background // Ability has back to background
console.log("[Demo] MainAbility onBackground"); console.log("[Demo] MainAbility onBackground");
} }
}; };
``` ```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册