Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
671fe771
D
Docs
项目概览
OpenHarmony
/
Docs
大约 1 年 前同步成功
通知
159
Star
292
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
671fe771
编写于
5月 18, 2023
作者:
O
openharmony_ci
提交者:
Gitee
5月 18, 2023
浏览文件
操作
浏览文件
下载
差异文件
!18039 【IPC&RPC】IPC&RPC通信章节新增指导内容
Merge pull request !18039 from Lixiaoying25/master
上级
de10c046
03df37c1
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
253 addition
and
184 deletion
+253
-184
zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md
...ication-dev/connectivity/ipc-rpc-development-guideline.md
+109
-69
zh-cn/application-dev/connectivity/ipc-rpc-overview.md
zh-cn/application-dev/connectivity/ipc-rpc-overview.md
+12
-22
zh-cn/application-dev/connectivity/subscribe-remote-state.md
zh-cn/application-dev/connectivity/subscribe-remote-state.md
+50
-14
zh-cn/application-dev/reference/apis/js-apis-rpc.md
zh-cn/application-dev/reference/apis/js-apis-rpc.md
+82
-79
未找到文件。
zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md
浏览文件 @
671fe771
...
...
@@ -29,7 +29,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
external_deps = [
"ipc:ipc_single",
]
#rpc场景
external_deps = [
"ipc:ipc_core",
...
...
@@ -50,12 +50,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```
c++
#include "iremote_broker.h"
//定义消息码
const
int
TRANS_ID_PING_ABILITY
=
5
const
int
TRANS_ID_PING_ABILITY
=
5
;
const
std
::
string
DESCRIPTOR
=
"test.ITestAbility"
;
class
ITestAbility
:
public
IRemoteBroker
{
public:
// DECLARE_INTERFACE_DESCRIPTOR是必需的,入参需使用std::u16string;
...
...
@@ -71,13 +71,13 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```
c++
#include "iability_test.h"
#include "iremote_stub.h"
class
TestAbilityStub
:
public
IRemoteStub
<
ITestAbility
>
{
public:
virtual
int
OnRemoteRequest
(
uint32_t
code
,
MessageParcel
&
data
,
MessageParcel
&
reply
,
MessageOption
&
option
)
override
;
int
TestPingAbility
(
const
std
::
u16string
&
dummy
)
override
;
};
int
TestAbilityStub
::
OnRemoteRequest
(
uint32_t
code
,
MessageParcel
&
data
,
MessageParcel
&
reply
,
MessageOption
&
option
)
{
...
...
@@ -98,12 +98,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```
c++
#include "iability_server_test.h"
class
TestAbility
:
public
TestAbilityStub
{
public:
int
TestPingAbility
(
const
std
::
u16string
&
dummy
);
}
int
TestAbility
::
TestPingAbility
(
const
std
::
u16string
&
dummy
)
{
return
0
;
}
...
...
@@ -117,7 +117,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
#include "iability_test.h"
#include "iremote_proxy.h"
#include "iremote_object.h"
class
TestAbilityProxy
:
public
IRemoteProxy
<
ITestAbility
>
{
public:
explicit
TestAbilityProxy
(
const
sptr
<
IRemoteObject
>
&
impl
);
...
...
@@ -125,12 +125,12 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
private:
static
inline
BrokerDelegator
<
TestAbilityProxy
>
delegator_
;
// 方便后续使用iface_cast宏
}
TestAbilityProxy
::
TestAbilityProxy
(
const
sptr
<
IRemoteObject
>
&
impl
)
:
IRemoteProxy
<
ITestAbility
>
(
impl
)
{
}
int
TestAbilityProxy
::
TestPingAbility
(
const
std
::
u16string
&
dummy
){
MessageOption
option
;
MessageParcel
dataParcel
,
replyParcel
;
...
...
@@ -149,7 +149,7 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
// 注册到本设备内
auto
samgr
=
SystemAbilityManagerClient
::
GetInstance
().
GetSystemAbilityManager
();
samgr
->
AddSystemAbility
(
saId
,
new
TestAbility
());
// 在组网场景下,会被同步到其他设备上
auto
samgr
=
SystemAbilityManagerClient
::
GetInstance
().
GetSystemAbilityManager
();
ISystemAbilityManager
::
SAExtraProp
saExtra
;
...
...
@@ -166,10 +166,10 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
sptr
<
ISystemAbilityManager
>
samgr
=
SystemAbilityManagerClient
::
GetInstance
().
GetSystemAbilityManager
();
sptr
<
IRemoteObject
>
remoteObject
=
samgr
->
GetSystemAbility
(
saId
);
sptr
<
ITestAbility
>
testAbility
=
iface_cast
<
ITestAbility
>
(
remoteObject
);
// 使用iface_cast宏转换成具体类型
// 获取其他设备注册的SA的proxy
sptr
<
ISystemAbilityManager
>
samgr
=
SystemAbilityManagerClient
::
GetInstance
().
GetSystemAbilityManager
();
// networkId是组网场景下对应设备的标识符,可以通过GetLocalNodeDeviceInfo获取
sptr
<
IRemoteObject
>
remoteObject
=
samgr
->
GetSystemAbility
(
saId
,
networkId
);
sptr
<
TestAbilityProxy
>
proxy
(
new
TestAbilityProxy
(
remoteObject
));
// 直接构造具体Proxy
...
...
@@ -180,59 +180,97 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
1.
添加依赖
```
ts
import
rpc
from
"
@ohos.rpc
"
import
featureAbility
from
"
@ohos.ability.featureAbility
"
import
rpc
from
"
@ohos.rpc
"
;
// 仅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
首先,构造变量want,指定要绑定的Ability所在应用的包名、组件名,如果是跨设备的场景,还需要绑定目标设备NetworkId(组网场景下对应设备的标识符,可以使用deviceManager获取目标设备的NetworkId);然后,构造变量connect,指定绑定成功、绑定失败、断开连接时的回调函数;最后,
使用featureAbility
提供的接口绑定Ability。
首先,构造变量want,指定要绑定的Ability所在应用的包名、组件名,如果是跨设备的场景,还需要绑定目标设备NetworkId(组网场景下对应设备的标识符,可以使用deviceManager获取目标设备的NetworkId);然后,构造变量connect,指定绑定成功、绑定失败、断开连接时的回调函数;最后,
FA模型使用featureAbility提供的接口绑定Ability,Stage模型通过context获取服务后用
提供的接口绑定Ability。
```
ts
import
rpc
from
"
@ohos.rpc
"
import
featureAbility
from
"
@ohos.ability.featureAbility
"
let
proxy
=
null
let
connectId
=
null
import
rpc
from
"
@ohos.rpc
"
;
// 仅FA模型需要导入@ohos.ability.featureAbility
// import featureAbility from "@ohos.ability.featureAbility";
let
proxy
=
null
;
let
connectId
=
null
;
// 单个设备绑定Ability
let
want
=
{
// 包名和组件名写实际的值
"
bundleName
"
:
"
ohos.rpc.test.server
"
,
"
abilityName
"
:
"
ohos.rpc.test.server.ServiceAbility
"
,
}
}
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remote
)
{
proxy
=
remote
proxy
=
remote
;
},
onDisconnect
:
function
(
elementName
)
{
},
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
import
deviceManager
from
'
@ohos.distributedHardware.deviceManager
'
import
deviceManager
from
'
@ohos.distributedHardware.deviceManager
'
;
function
deviceManagerCallback
(
deviceManager
)
{
let
deviceList
=
deviceManager
.
getTrustedDeviceListSync
()
let
networkId
=
deviceList
[
0
].
networkId
let
deviceList
=
deviceManager
.
getTrustedDeviceListSync
()
;
let
networkId
=
deviceList
[
0
].
networkId
;
let
want
=
{
"
bundleName
"
:
"
ohos.rpc.test.server
"
,
"
abilityName
"
:
"
ohos.rpc.test.service.ServiceAbility
"
,
"
networkId
"
:
networkId
,
"
flags
"
:
256
}
connectId
=
featureAbility
.
connectAbility
(
want
,
connect
)
};
// 建立连接后返回的Id需要保存下来,在断开连接时需要作为参数传入
// FA模型使用此方法连接服务
// connectId = featureAbility.connectAbility(want, connect);
connectId
=
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
}
// 第一个参数是本应用的包名,第二个参数是接收deviceManager的回调函数
deviceManager
.
createDeviceManager
(
"
ohos.rpc.test
"
,
deviceManagerCallback
)
deviceManager
.
createDeviceManager
(
"
ohos.rpc.test
"
,
deviceManagerCallback
)
;
```
3.
服务端处理客户端请求
...
...
@@ -240,78 +278,80 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
```
ts
onConnect
(
want
:
Want
)
{
var
robj
:
rpc
.
RemoteObject
=
new
Stub
(
"
rpcTestAbility
"
)
return
robj
var
robj
:
rpc
.
RemoteObject
=
new
Stub
(
"
rpcTestAbility
"
)
;
return
robj
;
}
class
Stub
extends
rpc
.
RemoteObject
{
constructor
(
descriptor
)
{
super
(
descriptor
)
super
(
descriptor
)
;
}
onRemoteMessageRequest
(
code
,
data
,
reply
,
option
)
{
// 根据code处理客户端的请求
return
true
return
true
;
}
}
```
4.
客户端处理服务端响应
客户端在onConnect回调里接收到代理对象,调用sendRequest
Async
方法发起请求,在期约(JavaScript期约:用于表示一个异步操作的最终完成或失败及其结果值)或者回调函数里接收结果。
客户端在onConnect回调里接收到代理对象,调用sendRequest方法发起请求,在期约(JavaScript期约:用于表示一个异步操作的最终完成或失败及其结果值)或者回调函数里接收结果。
```
ts
// 使用期约
let
option
=
new
rpc
.
MessageOption
()
let
data
=
rpc
.
MessageParcel
.
create
()
let
reply
=
rpc
.
MessageParcel
.
create
()
let
option
=
new
rpc
.
MessageOption
()
;
let
data
=
rpc
.
MessageParcel
.
create
()
;
let
reply
=
rpc
.
MessageParcel
.
create
()
;
// 往data里写入参数
proxy
.
sendRequest
Async
(
1
,
data
,
reply
,
option
)
proxy
.
sendRequest
(
1
,
data
,
reply
,
option
)
.
then
(
function
(
result
)
{
if
(
result
.
errCode
!=
0
)
{
console
.
error
(
"
send request failed, errCode:
"
+
result
.
errCode
)
return
console
.
error
(
"
send request failed, errCode:
"
+
result
.
errCode
)
;
return
;
}
// 从result.reply里读取结果
})
.
catch
(
function
(
e
)
{
console
.
error
(
"
send request got exception:
"
+
e
)
}
console
.
error
(
"
send request got exception:
"
+
e
)
;
}
)
.
finally
(()
=>
{
data
.
reclaim
()
reply
.
reclaim
()
data
.
reclaim
()
;
reply
.
reclaim
()
;
})
// 使用回调函数
function
sendRequestCallback
(
result
)
{
try
{
if
(
result
.
errCode
!=
0
)
{
console
.
error
(
"
send request failed, errCode:
"
+
result
.
errCode
)
return
console
.
error
(
"
send request failed, errCode:
"
+
result
.
errCode
)
;
return
;
}
// 从result.reply里读取结果
}
finally
{
result
.
data
.
reclaim
()
result
.
reply
.
reclaim
()
result
.
data
.
reclaim
()
;
result
.
reply
.
reclaim
()
;
}
}
let
option
=
new
rpc
.
MessageOption
()
let
data
=
rpc
.
MessageParcel
.
create
()
let
reply
=
rpc
.
MessageParcel
.
create
()
let
option
=
new
rpc
.
MessageOption
()
;
let
data
=
rpc
.
MessageParcel
.
create
()
;
let
reply
=
rpc
.
MessageParcel
.
create
()
;
// 往data里写入参数
proxy
.
sendRequest
(
1
,
data
,
reply
,
option
,
sendRequestCallback
)
proxy
.
sendRequest
(
1
,
data
,
reply
,
option
,
sendRequestCallback
)
;
```
5.
断开连接
IPC通信结束后,
使用featureAbility
的接口断开连接。
IPC通信结束后,
FA模型使用featureAbility的接口断开连接,Stage模型在获取context后用提供
的接口断开连接。
```
ts
import
rpc
from
"
@ohos.rpc
"
import
featureAbility
from
"
@ohos.ability.featureAbility
"
import
rpc
from
"
@ohos.rpc
"
;
// 仅FA模型需要导入@ohos.ability.featureAbility
// import featureAbility from "@ohos.ability.featureAbility";
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
);
```
zh-cn/application-dev/connectivity/ipc-rpc-overview.md
浏览文件 @
671fe771
...
...
@@ -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
)
## 约束与限制
-
单个设备上跨进程通信时,传输的数据量最大约为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的跨进程通信了。
> **说明:**
> 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机制提供远端接口调用与数据传递。
相关步骤:
-
实现接口类:需继承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
zh-cn/application-dev/connectivity/subscribe-remote-state.md
浏览文件 @
671fe771
# 远端状态订阅开发实例
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对象消
#include "iremote_broker.h"
#include "iremote_stub.h"
//定义消息码
enum {
TRANS_ID_PING_ABILITY = 5,
...
...
@@ -61,9 +60,6 @@ int TestServiceProxy::TestPingAbility(const std::u16string &dummy){
}
```
```
c++
#include "iremote_object.h"
...
...
@@ -86,16 +82,52 @@ result = object->RemoveDeathRecipient(deathRecipient); // 移除消亡通知
## JS侧接口
| 接口名 | 返回值类型 | 功能描述 |
| -------------------- | ---------- | ------------------------------------------------------------ |
| addDeathRecippient | boolean | 注册用于接收远程对象消亡通知的回调,增加proxy对象上的消亡通知。 |
| removeDeathRecipient | boolean | 注销用于接收远程对象消亡通知的回调。 |
| onRemoteDied | void | 在成功添加死亡通知订阅后,当远端对象死亡时,将自动调用本方法。 |
| 接口名 | 返回值类型 | 功能描述 |
| ------------------------ | ---------- | ----------------------------------------------------------------- |
| registerDeathRecipient | void | 注册用于接收远程对象消亡通知的回调,增加 proxy 对象上的消亡通知。 |
| unregisterDeathRecipient | 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
import
FA
from
"
@ohos.ability.featureAbility
"
;
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -113,15 +145,19 @@ let want = {
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
FA
.
connectAbility
(
want
,
connect
);
// FA模型通过此方法连接服务
// FA.connectAbility(want, connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
class
MyDeathRecipient
{
onRemoteDied
()
{
console
.
log
(
"
server died
"
);
}
}
let
deathRecipient
=
new
MyDeathRecipient
();
proxy
.
add
DeathRecippient
(
deathRecipient
,
0
);
proxy
.
remove
DeathRecipient
(
deathRecipient
,
0
);
proxy
.
register
DeathRecippient
(
deathRecipient
,
0
);
proxy
.
unregister
DeathRecipient
(
deathRecipient
,
0
);
```
## Stub感知Proxy消亡(匿名Stub的使用)
...
...
zh-cn/application-dev/reference/apis/js-apis-rpc.md
浏览文件 @
671fe771
...
...
@@ -2396,7 +2396,7 @@ readException(): void
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -2414,10 +2414,10 @@ readException(): void
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -4856,9 +4856,9 @@ readException(): void
Stage模型的应用在获取服务前需要先获取context,具体方法可参考
[
获取context
](
#获取context
)
```
ts
// 仅FA模型需要导入@ohos.ability.
;
featureAbility
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -4876,10 +4876,10 @@ readException(): void
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -5450,6 +5450,7 @@ marshalling(dataOut: MessageSequence): boolean
| 类型 | 说明 |
| ------- | -------------------------------- |
| boolean | true:封送成功,false:封送失败。|
**示例:**
```
ts
...
...
@@ -5555,6 +5556,7 @@ marshalling(dataOut: MessageParcel): boolean
| 类型 | 说明 |
| ------- | -------------------------------- |
| boolean | true:封送成功,false:封送失败。 |
**示例:**
```
ts
...
...
@@ -5671,7 +5673,7 @@ asObject(): IRemoteObject
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -5689,10 +5691,10 @@ asObject(): IRemoteObject
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6115,7 +6117,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6133,10 +6135,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6191,7 +6193,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6209,10 +6211,10 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6275,7 +6277,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6293,10 +6295,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6352,7 +6354,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6383,10 +6385,10 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
result
.
data
.
reclaim
();
result
.
reply
.
reclaim
();
}
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6433,7 +6435,7 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6464,10 +6466,10 @@ sendRequest(code: number, data: MessageParcel, reply: MessageParcel, options: Me
result
.
data
.
reclaim
();
result
.
reply
.
reclaim
();
}
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6517,7 +6519,7 @@ getLocalInterface(interface: string): IRemoteBroker
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6535,10 +6537,10 @@ getLocalInterface(interface: string): IRemoteBroker
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6583,7 +6585,7 @@ queryLocalInterface(interface: string): IRemoteBroker
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6601,10 +6603,10 @@ queryLocalInterface(interface: string): IRemoteBroker
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6645,7 +6647,7 @@ registerDeathRecipient(recipient: DeathRecipient, flags: number): void
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6663,10 +6665,10 @@ registerDeathRecipient(recipient: DeathRecipient, flags: number): void
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6717,7 +6719,7 @@ addDeathRecipient(recipient: DeathRecipient, flags: number): boolean
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6735,10 +6737,10 @@ addDeathRecipient(recipient: DeathRecipient, flags: number): boolean
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6784,7 +6786,7 @@ unregisterDeathRecipient(recipient: DeathRecipient, flags: number): void
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6802,10 +6804,10 @@ unregisterDeathRecipient(recipient: DeathRecipient, flags: number): void
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6857,7 +6859,7 @@ removeDeathRecipient(recipient: DeathRecipient, flags: number): boolean
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6875,10 +6877,10 @@ removeDeathRecipient(recipient: DeathRecipient, flags: number): boolean
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -6925,7 +6927,7 @@ getDescriptor(): string
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -6943,10 +6945,10 @@ getDescriptor(): string
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
上述onConnect回调函数中的proxy对象需要等ability异步连接成功后才会被赋值,然后才可调用proxy对象的getDescriptor接口方法获取对象的接口描述符
...
...
@@ -6984,7 +6986,7 @@ getInterfaceDescriptor(): string
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -7002,10 +7004,10 @@ getInterfaceDescriptor(): string
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -7037,7 +7039,7 @@ isObjectDead(): boolean
```
ts
// 仅FA模型需要导入@ohos.ability.featureAbility
// import FA from "@ohos.ability.featureAbility";
let
proxy
;
let
connect
=
{
onConnect
:
function
(
elementName
,
remoteProxy
)
{
...
...
@@ -7055,10 +7057,10 @@ isObjectDead(): boolean
"
bundleName
"
:
"
com.ohos.server
"
,
"
abilityName
"
:
"
com.ohos.server.EntryAbility
"
,
};
// FA模型使用此方法连接服务
// FA.connectAbility(want,connect);
globalThis
.
context
.
connectServiceExtensionAbility
(
want
,
connect
);
```
...
...
@@ -7093,9 +7095,9 @@ MessageOption构造函数。
**参数:**
| 参数名 | 类型
| 必填 | 说明 |
| --------- |
------ | ---- | -------------------------------------- |
| syncFlags | number
| 否 | 同步调用或异步调用标志。默认同步调用。 |
| 参数名 | 类型
| 必填 | 说明 |
| ------ | -
------ | ---- | -------------------------------------- |
| async | boolean
| 否 | 同步调用或异步调用标志。默认同步调用。 |
**示例:**
...
...
@@ -7823,7 +7825,7 @@ sendMessageRequest(code: number, data: MessageSequence, reply: MessageSequence,
| 类型 | 说明 |
| ---------------------------- | --------------------------------------------- |
| Promise
<
RequestResult
>
| 返回一个期约,兑现值是
sendRequestResult实例。
|
| Promise
<
RequestResult
>
| 返回一个期约,兑现值是
RequestResult实例。
|
**示例:**
...
...
@@ -9099,30 +9101,31 @@ readFromAshmem(size: number, offset: number): number[]
```
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
"
);
}
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
"
);
}
};
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录