1# 分布式数据对象开发指导 2 3## 场景介绍 4 5分布式数据对象为开发者在分布式应用场景下提供简单易用的功能接口,可实现多设备间同应用的数据协同,同时设备间还可以监听对象的状态和数据变更。 6 7比如,当设备1上应用A的分布式数据对象增、删、改数据后,设备2上应用A也可以获取到对应的数据变化,同时还能监听数据变更以及对端数据对象的上下线。 8 9## 接口说明 10 11分布式数据对象相关功能接口请见[分布式数据对象](../reference/apis/js-apis-data-distributedobject.md)。 12 13### 创建数据对象实例 14 15创建一个分布式数据对象实例,开发者可以通过source指定分布式数据对象中的属性。 16 17 18**表1** 分布式数据对象实例创建接口 19 20| 包名 | 接口名 | 描述 | 21| -------- | -------- | -------- | 22| ohos.data.distributedDataObject| createDistributedObject(source: object): DistributedObject | 创建一个分布式数据对象实例,用于数据操作。 <br>- source:设置分布式数据对象的属性。<br>- DistributedObject:返回值是创建好的分布式数据对象。 | 23 24### 创建分布式数据对象sessionId 25 26创建一个随机的sessionId,可将其设置为一个分布式数据对象的sessionId。 27 28**表2** 分布式数据对象sessionId创建接口 29 30| 包名 | 接口名 | 描述 | 31| -------- | -------- | -------- | 32| ohos.data.distributedDataObject| genSessionId(): string | 创建一个sessionId,可作为分布式数据对象的sessionId。 | 33 34### 设置分布式数据对象sessionId 35 36设置分布式数据对象的sessionId,sessionId是一次(多设备)协同的唯一标识,同步的多个数据对象需要关联同一个sessionId。 37 38**表3** 分布式数据对象sessionId设置接口 39 40| 类名 | 接口名 | 描述 | 41| -------- | -------- | -------- | 42| DistributedDataObject | setSessionId(sessionId?: string): boolean | 为分布式数据对象设置sessionId。<br> sessionId:分布式数据对象在可信组网中的标识ID。如果要退出分布式组网,设置为""或不设置均可。 | 43 44### 订阅数据变更 45 46订阅数据变更需要指定Callback作为回调方法,订阅的数据对象发生数据变更后,Callback被回调。 47 48**表4** 分布式数据对象数据变更订阅接口 49 50| 类名 | 接口名 | 描述 | 51| -------- | -------- | -------- | 52| DistributedDataObject| on(type: 'change', callback: Callback<{ sessionId: string, fields: Array<string> }>): void | 订阅数据变更。 | 53| DistributedDataObject| off(type: 'change', callback?: Callback<{ sessionId: string, fields: Array<string> }>): void | 注销订阅。需要删除的变更回调,若不设置则删除该对象所有的变更回调。 | 54 55### 订阅数据对象上下线 56 57订阅数据对象上下线需要指定Callback作为回调方法,订阅的数据对象上线/下线后,对端的数据对象会收到Callback回调。 58 59**表5** 分布式数据对象数据上下线订阅接口 60 61| 类名 | 接口名 | 描述 | 62| -------- | -------- | -------- | 63| DistributedDataObject| on(type: 'status', callback: Callback<{ sessionId: string, networkId: string, status: 'online' \| 'offline' }>): void | 订阅数据对象上下线。 | 64| DistributedDataObject| off(type: 'status', callback?: Callback<{ sessionId: string, deviceId: string, status: 'online' \| 'offline' }>): void | 注销订阅。 | 65 66### 保存和撤回已保存的数据对象 67 68保存数据对象:数据对象保存成功后,当应用存在时不会释放对象数据;当应用退出后,重新进入应用时,恢复保存在设备上的数据。 69 70撤回保存的数据对象:如果该对象保存在本地设备,那么将删除所有受信任设备上所保存的数据;如果对象保存在其他设备,那么将删除本地设备上的数据。 71 72有以下几种情况时,保存的数据将会被释放: 73 74- 存储时间超过24小时。 75- 应用卸载。 76- 成功恢复数据之后。 77 78**表6** 分布式数据对象保存和撤回保存接口 79 80| 类名 | 接口名 | 描述 | 81| -------- | -------- | -------- | 82| DistributedDataObject | save(deviceId: string): Promise<SaveSuccessResponse> | 保存数据对象。 | 83| DistributedDataObject| revokeSave(): Promise<RevokeSaveSuccessResponse> | 撤回已保存的数据对象。 | 84 85## 开发步骤 86 87以一次分布式数据对象同步为例,说明开发步骤。 88 891. 准备工作,导入@ohos.data.distributedDataObject模块到开发环境。 90 91 ```js 92 import distributedObject from '@ohos.data.distributedDataObject'; 93 ``` 942. 请求权限。 95 96 需要在`config.json`文件里进行配置请求权限(FA模型)。 97 98 ```json 99 { 100 "module": { 101 "reqPermissions": [ 102 { 103 "name": "ohos.permission.DISTRIBUTED_DATASYNC" 104 } 105 ] 106 } 107 } 108 ``` 109 Stage模型下的权限请求请参见[权限声明-Stage模型](../security/accesstoken-guidelines.md#stage模型)。 110 111 这个权限还需要在应用首次启动的时候弹窗获取用户授权。 112 113 ```js 114 // FA模型 115 import featureAbility from '@ohos.ability.featureAbility'; 116 117 function grantPermission() { 118 console.info('grantPermission'); 119 let context = featureAbility.getContext(); 120 context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) { 121 console.info(`requestPermissionsFromUser CallBack`); 122 123 }) 124 console.info('end grantPermission'); 125 } 126 127 grantPermission(); 128 ``` 129 130 ```ts 131 // Stage模型 132 import UIAbility from '@ohos.app.ability.UIAbility'; 133 134 let context = null; 135 136 class EntryAbility extends UIAbility { 137 onWindowStageCreate(windowStage) { 138 context = this.context; 139 } 140 } 141 142 function grantPermission() { 143 let permissions = ['ohos.permission.DISTRIBUTED_DATASYNC']; 144 context.requestPermissionsFromUser(permissions).then((data) => { 145 console.info('success: ${data}'); 146 }).catch((error) => { 147 console.error('failed: ${error}'); 148 }); 149 } 150 151 grantPermission(); 152 ``` 153 1543. 获取分布式数据对象实例。 155 156 ```js 157 let localObject = distributedObject.createDistributedObject({ 158 name: undefined, 159 age: undefined, 160 isVis: true, 161 parent: undefined, 162 list: undefined 163 }); 164 let sessionId = distributedObject.genSessionId(); 165 ``` 166 1674. 加入同步组网。同步组网中的数据对象分为发起方和被拉起方。 168 169 ```js 170 // 发起方 171 let localObject = distributedObject.createDistributedObject({ 172 name: "jack", 173 age: 18, 174 isVis: true, 175 parent: { mother: "jack mom", father: "jack Dad" }, 176 list: [{ mother: "jack mom" }, { father: "jack Dad" }] 177 }); 178 localObject.setSessionId(sessionId); 179 180 // 被拉起方 181 let remoteObject = distributedObject.createDistributedObject({ 182 name: undefined, 183 age: undefined, 184 isVis: true, 185 parent: undefined, 186 list: undefined 187 }); 188 // 收到status上线后remoteObject同步数据,即name变成jack,age是18 189 remoteObject.setSessionId(sessionId); 190 ``` 191 1925. 监听对象数据变更。可监听对端数据的变更,以Callback作为变更回调实例。 193 194 ```js 195 function changeCallback(sessionId, changeData) { 196 console.info("change" + sessionId); 197 198 if (changeData != null && changeData != undefined) { 199 changeData.forEach(element => { 200 console.info("changed !" + element + " " + localObject[element]); 201 }); 202 } 203 } 204 205 // 发起方要在changeCallback里刷新界面,则需要将正确的this绑定给changeCallback 206 localObject.on("change", this.changeCallback.bind(this)); 207 ``` 208 2096. 修改对象属性,对象属性支持基本类型(数字类型、布尔类型、字符串类型)以及复杂类型(数组、基本类型嵌套等)。 210 211 ```js 212 localObject.name = "jack"; 213 localObject.age = 19; 214 localObject.isVis = false; 215 localObject.parent = { mother: "jack mom", father: "jack Dad" }; 216 localObject.list = [{ mother: "jack mom" }, { father: "jack Dad" }]; 217 ``` 218 219 > **说明:** 220 > 针对复杂类型的数据修改,目前支持对根属性的修改,暂不支持对下级属性的修改。 221 222 ```js 223 // 支持的修改方式 224 localObject.parent = { mother: "mom", father: "dad" }; 225 // 不支持的修改方式 226 localObject.parent.mother = "mom"; 227 ``` 228 2297. 访问对象。可以通过直接获取的方式访问到分布式数据对象的属性,且该数据为组网内的最新数据。 230 231 ```js 232 console.info("name " + localObject["name"]); 233 ``` 2348. 删除监听数据变更。可以指定删除监听的数据变更回调;也可以不指定,这将会删除该分布式数据对象的所有数据变更回调。 235 236 ```js 237 // 删除变更回调changeCallback 238 localObject.off("change", changeCallback); 239 // 删除所有的变更回调 240 localObject.off("change"); 241 ``` 2429. 监听分布式数据对象的上下线。可以监听对端分布式数据对象的上下线。 243 244 ```js 245 function statusCallback(sessionId, networkId, status) { 246 this.response += "status changed " + sessionId + " " + status + " " + networkId; 247 } 248 249 localObject.on("status", this.statusCallback); 250 ``` 251 25210. 保存和撤回已保存的数据对象。 253 254 ```js 255 // 保存数据对象 256 localObject.save("local").then((result) => { 257 console.info("save sessionId " + result.sessionId); 258 console.info("save version " + result.version); 259 console.info("save deviceId " + result.deviceId); 260 }, (result) => { 261 console.info("save local failed."); 262 }); 263 // 撤回保存的数据对象 264 localObject.revokeSave().then((result) => { 265 console.info("revokeSave success."); 266 }, (result) => { 267 console.info("revokeSave failed."); 268 }); 269 ``` 27011. 删除监听分布式数据对象的上下线。可以指定删除监听的上下线回调;也可以不指定,这将会删除该分布式数据对象的所有上下线回调。 271 272 ```js 273 // 删除上下线回调statusCallback 274 localObject.off("status", this.statusCallback); 275 // 删除所有的上下线回调 276 localObject.off("status"); 277 ``` 27812. 退出同步组网。分布式数据对象退出组网后,本地的数据变更对端不会同步。 279 280 ```js 281 localObject.setSessionId(""); 282 ``` 283 284## 相关实例 285 286针对分布式数据对象,有以下相关实例可供参考: 287- [`DistributedNote`:分布式备忘录(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/data/DistributedNote) 288- [`DistributedObjectDms`:分布式跑马灯(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/data/DistributedObjectDms)