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

## 场景介绍

分布式数据对象通过屏蔽设备间复杂的数据交互处理,提供了与本地变量类似的极简操作,当设备1的应用A的分布式数据对象增、删、改数据后,设备2的应用A也可以获取到对应的数据变化,同时还能监听数据变更以及对端数据对象的上下线。分布式数据对象支持的数据类型包括数字型、字符型、布尔型等基本类型,同时也支持数组、基本类型嵌套等复杂类型。


## 接口说明

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

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

创建一个分布式数据对象实例,用户可以通过source指定分布式对象中的属性。


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

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

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

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

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

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

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

### 订阅数据变更

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

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

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

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

**表5** 分布式数据对象数据上下线订阅接口
L
li_juntao 已提交
55
| 类名 | 接口名 | 描述 |
L
li_juntao 已提交
56
| -------- | -------- | -------- |
L
li_juntao 已提交
57 58
| 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 已提交
59

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

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

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

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

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

**表6** 分布式数据对象保存和撤回保存接口
| 类名 | 接口名 | 描述 |
| -------- | -------- | -------- |
| DistributedDataObject | save(deviceId: string): Promise&lt;SaveSuccessResponse&gt; | 保存数据对象。 |
W
wangxiyue 已提交
76 77
| DistributedDataObject| save(deviceId: string, callback: AsyncCallback&lt;SaveSuccessResponse&gt;): void | 保存数据对象。 |
| DistributedDataObject | revokeSave(callback: AsyncCallback&lt;RevokeSaveSuccessResponse&gt;): void | 撤回已保存的数据对象。 |
78
| DistributedDataObject| revokeSave(): Promise&lt;RevokeSaveSuccessResponse&gt; | 撤回已保存的数据对象。 |
L
li_juntao 已提交
79 80 81 82 83 84

## 开发步骤

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

1. 准备工作,导入@ohos.data.distributedDataObject模块到开发环境。
W
wufengshan 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
   ```js   
   import distributedObject from '@ohos.data.distributedDataObject';   
   ```   
2. 请求权限。需要在`config.json`里面进行配置请求权限,示例代码如下:
    ```
     {
       "module": {
           "reqPermissions": [
               {
                  "name": "ohos.permission.DISTRIBUTED_DATASYNC"
               }
           ]
       }
     }
    ```	 
    这个权限还需要在应用首次启动的时候弹窗获取用户授权,可以通过如下代码实现:
    ```js
    import featureAbility from '@ohos.ability.featureAbility';
	
    function grantPermission() {
        console.info('grantPermission');
        let context = featureAbility.getContext();
        context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) {
            console.info(`result.requestCode=${result.requestCode}`)
    
        })
        console.info('end grantPermission');
    }
    grantPermission();
    ```
L
li_juntao 已提交
115

W
wufengshan 已提交
116
3. 获取分布式数据对象实例。
L
li_juntao 已提交
117 118 119

   以下为创建分布式数据对象的代码示例:
   ```js
L
li_juntao 已提交
120 121
   var local_object = distributedObject.createDistributedObject({name:undefined, age:undefined, isVis:true, 
                  parent:undefined, list:undefined});
122
   var sessionId = distributedObject.genSessionId();
L
li_juntao 已提交
123 124 125
   ```


W
wufengshan 已提交
126
4. 加入同步组网。同步组网中的数据对象分为发起方和被拉起方。
127
   
L
li_juntao 已提交
128 129 130
   以下为加入同步组网的代码示例:

   ```js
L
li_juntao 已提交
131 132
   //发起方
   var local_object = distributedObject.createDistributedObject({name:"jack", age:18, isVis:true, 
133
       parent:{mother:"jack mom",father:"jack Dad"},list:[{mother:"jack mom"}, {father:"jack Dad"}]});
134
   local_object.setSessionId(sessionId);
L
li_juntao 已提交
135
   
136
   //被拉起方
L
li_juntao 已提交
137 138
   var remote_object = distributedObject.createDistributedObject({name:undefined, age:undefined, isVis:true, 
                  parent:undefined, list:undefined});
139
   remote_object.setSessionId(sessionId);
L
li_juntao 已提交
140
   //收到status上线后remote_object同步数据,即name变成jack,age是18
L
li_juntao 已提交
141
   ```
L
li_juntao 已提交
142
   
W
wufengshan 已提交
143
5. 监听对象数据变更。可监听对端数据的变更,以callback作为变更回调实例。
L
li_juntao 已提交
144 145 146 147

   以下为监听对象数据变更的代码示例。
   
   ```js
148
   function changeCallback(sessionId, changeData) {
L
li_juntao 已提交
149
        console.info("change" + sessionId);
L
li_juntao 已提交
150
   
L
li_juntao 已提交
151 152 153
        if (changeData != null && changeData != undefined) {
            changeData.forEach(element => {
                console.info("changed !" + element + " " + local_object[element]);
154
        });
L
li_juntao 已提交
155 156
        }
    } 
157 158 159

    // 发起方要在changeCallback里刷新界面,则需要将正确的this绑定给changeCallback
    local_object.on("change", this.changeCallback.bind(this));
L
li_juntao 已提交
160
   ```
L
li_juntao 已提交
161
   
W
wufengshan 已提交
162
6. 修改对象属性,对象属性支持基本类型(数字类型、布尔类型、字符串类型)以及复杂类型(数组、基本类型嵌套等)。
163
   
L
li_juntao 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
   以下为修改分布式数据对象属性的代码示例:
   ```js
   local_object.name = "jack";
   local_object.age = 19;
   local_object.isVis = false;
   local_object.parent = {mother:"jack mom",father:"jack Dad"};
   local_object.list = [{mother:"jack mom"}, {father:"jack Dad"}];
   ```

   > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
   > 针对复杂类型的数据修改,目前支持对根属性的修改,暂不支持对下级属性的修改。示例如下:
   ```js
   //支持的修改方式
   local_object.parent = {mother:"mom", father:"dad"};
   //不支持的修改方式
   local_object.parent.mother = "mom";
   ```

W
wufengshan 已提交
182
7. 访问对象。可以通过直接获取的方式访问到分布式数据对象的属性,且该数据为组网内的最新数据。
183
   
L
li_juntao 已提交
184 185 186 187
   以下为访问对象的代码示例:
   ```js
   console.info("name " + local_object["name"]); 
   ```
W
wufengshan 已提交
188
8. 删除监听数据变更。可以指定删除监听的数据变更回调;也可以不指定,这将会删除该分布式数据对象的所有数据变更回调。
L
li_juntao 已提交
189 190 191 192 193 194 195 196

   以下为取消监听数据变更的代码示例:
   ```js
   //删除变更回调changeCallback
   local_object.off("change", changeCallback);
   //删除所有的变更回调
   local_object.off("change"); 
   ```
W
wufengshan 已提交
197
9. 监听分布式对象的上下线。可以监听对端分布式数据对象的上下线。
L
li_juntao 已提交
198 199
   以下为访问对象的代码示例:
   ```js
200
    function statusCallback(sessionId, networkId, status) {
L
li_juntao 已提交
201 202
      this.response += "status changed " + sessionId + " " + status + " " + networkId;
    }
L
li_juntao 已提交
203
   
204
    local_object.on("status", this.statusCallback);
L
li_juntao 已提交
205
   ```
206 207

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

    1.callback方式
    
211 212 213 214 215 216 217 218 219 220 221 222 223 224
       ```js
        // 保存数据对象
        local_object.save("local", (result, data)=>{
            console.log("save callback");
            console.info("save sessionId " + data.sessionId);
            console.info("save version " + data.version);
            console.info("save deviceId " + data.deviceId);
        });
        // 撤回保存的数据对象
        local_object.revokeSave((result, data) =>{
        console.log("revokeSave callback");
        console.info("revokeSave sessionId " + data.sessionId);
        });
       ```
W
wangxiyue 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
       2.Promise方式
       ```js
        // 保存数据对象
        g_object.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.");
        });
        // 撤回保存的数据对象
        g_object.revokeSave().then((result)=>{
            console.info("revokeSave success.");
        }, (result)=>{
            console.info("revokeSave failed.");
        });
       ```
242 243
11. 删除监听分布式对象的上下线。可以指定删除监听的上下线回调;也可以不指定,这将会删除该分布式数据对象的所有上下线回调。

L
li_juntao 已提交
244
    以下为取消监听数据变更的代码示例:
245
       ```js
W
wangxiyue 已提交
246 247 248 249
    //删除上下线回调statusCallback
    local_object.off("status", this.statusCallback);
    //删除所有的上下线回调
    local_object.off("status");
250 251
       ```
12. 退出同步组网。分布式对象退出组网后,本地的数据变更对端不会同步。
L
li_juntao 已提交
252 253 254 255 256

     以下为退出同步组网的代码示例:
       ```js
       local_object.setSessionId("");
       ```
257
## 开发实例
258

W
wangxiyue 已提交
259
针对分布式数据对象,有以下开发实例可供参考:
L
li_juntao 已提交
260

261 262
- [备忘录应用](https://gitee.com/openharmony/distributeddatamgr_objectstore/tree/master/samples/distributedNotepad)

L
li_juntao 已提交
263

264
在备忘录应用中,当某一个设备上的备忘录事件发生变更时,通过分布式数据对象将事件变更同步在可信组网内的其他设备上,比如新增备忘录事件、编辑事件标题和内容、清空事件列表等。
W
wangxiyue 已提交
265