database-distributedobject-guidelines.md 10.6 KB
Newer Older
L
li_juntao 已提交
1 2 3 4
# 分布式数据对象开发指导

## 场景介绍

5
分布式数据对象为开发者在分布式应用场景下提供简单易用的功能接口,可实现多设备间同应用的数据协同,同时设备间还可以监听对象的状态和数据变更。
L
li_juntao 已提交
6

7
比如,当设备1上应用A的分布式数据对象增、删、改数据后,设备2上应用A也可以获取到对应的数据变化,同时还能监听数据变更以及对端数据对象的上下线。
L
li_juntao 已提交
8 9 10

## 接口说明

11
分布式数据对象相关功能接口请见[分布式数据对象](../reference/apis/js-apis-data-distributedobject.md)
12

L
li_juntao 已提交
13 14
### 创建数据对象实例

15
创建一个分布式数据对象实例,开发者可以通过source指定分布式对象中的属性。
L
li_juntao 已提交
16 17 18


**表1** 分布式数据对象实例创建接口
19

20
| 包名 | 接口名 | 描述 |
L
li_juntao 已提交
21
| -------- | -------- | -------- |
22
| ohos.data.distributedDataObject| createDistributedObject(source: object): DistributedObject | 创建一个分布式数据对象实例,用于数据操作。 <br>-&nbsp;source:设置distributedObject的属性。<br>-&nbsp;DistributedObject:返回值是创建好的分布式对象。 |
L
li_juntao 已提交
23 24 25 26 27 28

### 创建分布式数据对象sessionId

创建一个随机的sessionId,可将其设置为一个分布式数据对象的sessionId。

**表2** 分布式数据对象sessionId创建接口
29

L
li_juntao 已提交
30
| 包名 | 接口名 | 描述 |
L
li_juntao 已提交
31
| -------- | -------- | -------- |
32
| ohos.data.distributedDataObject| genSessionId(): string | 创建一个sessionId,可作为分布式数据对象的sessionId。 |
L
li_juntao 已提交
33 34 35 36 37 38

### 设置分布式数据对象sessionId

设置分布式数据对象的sessionId,sessionId是一次(多设备)协同的唯一标识,同步的多个数据对象需要关联同一个sessionId。

**表3** 分布式数据对象sessionId设置接口
39

L
li_juntao 已提交
40
| 类名 | 接口名 | 描述 |
L
li_juntao 已提交
41
| -------- | -------- | -------- |
42
| DistributedDataObject | setSessionId(sessionId?: string): boolean | 为分布式数据对象设置sessionId。<br>&nbsp;sessionId:分布式对象在可信组网中的标识ID。如果要退出分布式组网,设置为""或不设置均可。 |
L
li_juntao 已提交
43 44 45 46 47 48

### 订阅数据变更

订阅数据变更需要指定Callback作为回调方法,订阅的数据对象发生数据变更后,Callback被回调。

**表4** 分布式数据对象数据变更订阅接口
49 50

| 类名 | 接口名 | 描述 |
L
li_juntao 已提交
51
| -------- | -------- | -------- |
52
| DistributedDataObject| on(type: 'change', callback: Callback<{ sessionId: string, fields: Array&lt;string&gt; }>): void | 订阅数据变更。 |
W
wuyongning 已提交
53
| DistributedDataObject| off(type: 'change', callback?: Callback<{ sessionId: string, fields: Array&lt;string&gt; }>): void | 注销订阅。需要删除的变更回调,若不设置则删除该对象所有的变更回调。 |
L
li_juntao 已提交
54 55 56 57 58 59

### 订阅数据对象上下线

订阅数据对象上下线需要指定Callback作为回调方法,订阅的数据对象上线/下线后,对端的数据对象会收到Callback回调。

**表5** 分布式数据对象数据上下线订阅接口
60

L
li_juntao 已提交
61
| 类名 | 接口名 | 描述 |
L
li_juntao 已提交
62
| -------- | -------- | -------- |
L
li_juntao 已提交
63 64
| DistributedDataObject| on(type: 'status', callback: Callback<{ sessionId: string, networkId: string, status: 'online' \| 'offline' }>): void | 订阅数据对象上下线。 |
| DistributedDataObject| off(type: 'status', callback?: Callback<{ sessionId: string, deviceId: string, status: 'online' \| 'offline' }>): void | 注销订阅。 |
L
li_juntao 已提交
65

66
### 保存和撤回已保存的数据对象
L
li_juntao 已提交
67

68 69 70 71 72 73 74 75 76 77 78
保存数据对象:数据对象保存成功后,当应用存在时不会释放对象数据;当应用退出后,重新进入应用时,恢复保存在设备上的数据。

撤回保存的数据对象:如果该对象保存在本地设备,那么将删除所有受信任设备上所保存的数据;如果对象保存在其他设备,那么将删除本地设备上的数据。

有以下几种情况时,保存的数据将会被释放:

- 存储时间超过24小时。
- 应用卸载。
- 成功恢复数据之后。

**表6** 分布式数据对象保存和撤回保存接口
79

80 81 82 83
| 类名 | 接口名 | 描述 |
| -------- | -------- | -------- |
| DistributedDataObject | save(deviceId: string): Promise&lt;SaveSuccessResponse&gt; | 保存数据对象。 |
| DistributedDataObject| revokeSave(): Promise&lt;RevokeSaveSuccessResponse&gt; | 撤回已保存的数据对象。 |
L
li_juntao 已提交
84 85 86 87 88 89

## 开发步骤

以一次分布式数据对象同步为例,说明开发步骤。

1. 准备工作,导入@ohos.data.distributedDataObject模块到开发环境。
90

W
wufengshan 已提交
91 92
   ```js   
   import distributedObject from '@ohos.data.distributedDataObject';   
93
   ```
94 95 96
2. 请求权限。

   需要在`config.json`文件里进行配置请求权限(FA模型),示例代码如下:
97

“wangxiyue” 已提交
98 99
   ```json
   {
W
wufengshan 已提交
100 101 102
       "module": {
           "reqPermissions": [
               {
“wangxiyue” 已提交
103
                   "name": "ohos.permission.DISTRIBUTED_DATASYNC"
W
wufengshan 已提交
104 105 106
               }
           ]
       }
“wangxiyue” 已提交
107 108
   }
   ```
109 110 111
   Stage模型下的权限请求请参见[权限声明-Stage模型](../security/accesstoken-guidelines.md#stage模型)

   这个权限还需要在应用首次启动的时候弹窗获取用户授权,可以通过如下代码实现:
112

“wangxiyue” 已提交
113 114
   ```js
   import featureAbility from '@ohos.ability.featureAbility';
W
wufengshan 已提交
115
	
“wangxiyue” 已提交
116 117 118 119 120
   function grantPermission() {
       console.info('grantPermission');
       let context = featureAbility.getContext();
       context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) {
           console.info(`result.requestCode=${result.requestCode}`)
W
wufengshan 已提交
121
    
“wangxiyue” 已提交
122 123 124
       })
       console.info('end grantPermission');
   }
125
    
“wangxiyue” 已提交
126 127
   grantPermission();
   ```
128
    
W
wufengshan 已提交
129
3. 获取分布式数据对象实例。
L
li_juntao 已提交
130 131

   以下为创建分布式数据对象的代码示例:
132

L
li_juntao 已提交
133
   ```js
“wangxiyue” 已提交
134 135 136 137 138 139
   let localObject = distributedObject.createDistributedObject({
       name: undefined,
       age: undefined,
       isVis: true,
       parent: undefined,
       list: undefined
140
   });
“wangxiyue” 已提交
141
   let sessionId = distributedObject.genSessionId();
L
li_juntao 已提交
142 143
   ```

W
wufengshan 已提交
144
4. 加入同步组网。同步组网中的数据对象分为发起方和被拉起方。
145
   
L
li_juntao 已提交
146 147 148
   以下为加入同步组网的代码示例:

   ```js
149
   // 发起方
“wangxiyue” 已提交
150 151 152 153 154 155
   let localObject = distributedObject.createDistributedObject({
       name: "jack",
       age: 18,
       isVis: true,
       parent: { mother: "jack mom", father: "jack Dad" },
       list: [{ mother: "jack mom" }, { father: "jack Dad" }]
156
   });
“wangxiyue” 已提交
157
   localObject.setSessionId(sessionId);
“wangxiyue” 已提交
158
   
159
   // 被拉起方
“wangxiyue” 已提交
160 161 162 163 164 165
   let remoteObject = distributedObject.createDistributedObject({
       name: undefined,
       age: undefined,
       isVis: true,
       parent: undefined,
       list: undefined
166
   });
167
   // 收到status上线后remote_object同步数据,即name变成jack,age是18
“wangxiyue” 已提交
168
   remoteObject.setSessionId(sessionId);
L
li_juntao 已提交
169
   ```
“wangxiyue” 已提交
170

“wangxiyue” 已提交
171
5. 监听对象数据变更。可监听对端数据的变更,以Callback作为变更回调实例。
L
li_juntao 已提交
172 173 174 175

   以下为监听对象数据变更的代码示例。
   
   ```js
176
   function changeCallback(sessionId, changeData) {
177
       console.info("change" + sessionId);
L
li_juntao 已提交
178
   
179 180
       if (changeData != null && changeData != undefined) {
           changeData.forEach(element => {
“wangxiyue” 已提交
181 182
               console.info("changed !" + element + " " + localObject[element]);
           });
183 184 185 186
       }
   } 

   // 发起方要在changeCallback里刷新界面,则需要将正确的this绑定给changeCallback
“wangxiyue” 已提交
187
   localObject.on("change", this.changeCallback.bind(this));
L
li_juntao 已提交
188
   ```
“wangxiyue” 已提交
189
   
W
wufengshan 已提交
190
6. 修改对象属性,对象属性支持基本类型(数字类型、布尔类型、字符串类型)以及复杂类型(数组、基本类型嵌套等)。
191
   
L
li_juntao 已提交
192
   以下为修改分布式数据对象属性的代码示例:
193

L
li_juntao 已提交
194
   ```js
“wangxiyue” 已提交
195 196 197 198 199
   localObject.name = "jack";
   localObject.age = 19;
   localObject.isVis = false;
   localObject.parent = { mother: "jack mom", father: "jack Dad" };
   localObject.list = [{ mother: "jack mom" }, { father: "jack Dad" }];
L
li_juntao 已提交
200 201
   ```

202
   > **说明:**
L
li_juntao 已提交
203
   > 针对复杂类型的数据修改,目前支持对根属性的修改,暂不支持对下级属性的修改。示例如下:
204

L
li_juntao 已提交
205
   ```js
206
   // 支持的修改方式
“wangxiyue” 已提交
207
   localObject.parent = { mother: "mom", father: "dad" };
208
   // 不支持的修改方式
“wangxiyue” 已提交
209
   localObject.parent.mother = "mom";
L
li_juntao 已提交
210 211
   ```

W
wufengshan 已提交
212
7. 访问对象。可以通过直接获取的方式访问到分布式数据对象的属性,且该数据为组网内的最新数据。
213
   
L
li_juntao 已提交
214
   以下为访问对象的代码示例:
215

L
li_juntao 已提交
216
   ```js
“wangxiyue” 已提交
217
   console.info("name " + localObject["name"]); 
L
li_juntao 已提交
218
   ```
W
wufengshan 已提交
219
8. 删除监听数据变更。可以指定删除监听的数据变更回调;也可以不指定,这将会删除该分布式数据对象的所有数据变更回调。
L
li_juntao 已提交
220 221

   以下为取消监听数据变更的代码示例:
222

L
li_juntao 已提交
223
   ```js
224
   // 删除变更回调changeCallback
“wangxiyue” 已提交
225
   localObject.off("change", changeCallback);
226
   // 删除所有的变更回调
“wangxiyue” 已提交
227
   localObject.off("change"); 
L
li_juntao 已提交
228
   ```
W
wufengshan 已提交
229
9. 监听分布式对象的上下线。可以监听对端分布式数据对象的上下线。
L
li_juntao 已提交
230
   以下为访问对象的代码示例:
231

L
li_juntao 已提交
232
   ```js
“wangxiyue” 已提交
233 234 235
   function statusCallback(sessionId, networkId, status) {
       this.response += "status changed " + sessionId + " " + status + " " + networkId;
   }
“wangxiyue” 已提交
236
   
“wangxiyue” 已提交
237
   localObject.on("status", this.statusCallback);
L
li_juntao 已提交
238
   ```
239 240

10. 保存和撤回已保存的数据对象。
W
wangxiyue 已提交
241

“wangxiyue” 已提交
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
   ```js
   // 保存数据对象
   localObject.save("local").then((result) => {
       console.info("save sessionId " + result.sessionId);
       console.info("save version " + result.version);
       console.info("save deviceId " + result.deviceId);
   }, (result) => {
       console.info("save local failed.");
   });
   // 撤回保存的数据对象
   localObject.revokeSave().then((result) => {
       console.info("revokeSave success.");
   }, (result) => {
       console.info("revokeSave failed.");
   });
   ```
258 259
11. 删除监听分布式对象的上下线。可以指定删除监听的上下线回调;也可以不指定,这将会删除该分布式数据对象的所有上下线回调。

“wangxiyue” 已提交
260
   以下为取消监听数据变更的代码示例:
261

“wangxiyue” 已提交
262 263 264 265 266 267
   ```js
   // 删除上下线回调statusCallback
   localObject.off("status", this.statusCallback);
   // 删除所有的上下线回调
   localObject.off("status");
   ```
268
12. 退出同步组网。分布式对象退出组网后,本地的数据变更对端不会同步。
L
li_juntao 已提交
269

“wangxiyue” 已提交
270
   以下为退出同步组网的代码示例:
271

“wangxiyue” 已提交
272 273 274
   ```js
   localObject.setSessionId("");
   ```
275

276
## 相关实例
277

278
针对分布式数据对象,有以下相关实例可供参考:
279
- [`DistributedNote`:分布式备忘录(eTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/data/DistributedNote)
280
- [`DistributedObjectDms`:分布式跑马灯(eTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/data/DistributedObjectDms)