> 文档中心 > 【OpenHarmony应用开发】分布式数据对象

【OpenHarmony应用开发】分布式数据对象


分布式数据对象概述

分布式数据对象管理框架是一款面向对象的内存数据管理框架。向应用开发者提供内存对象的创建、查询、删除、修改、订阅等基本数据对象的管理能力;同时具备分布式能力,满足超级终端场景下,相同应用多设备间的数据对象协同需求。

基本概念

  • 分布式内存数据库

    分布式内存数据库将数据缓存在内存中,以便应用获得更快的数据存取速度,不会将数据进行持久化。若数据库关闭,则数据不会保留。

  • 分布式数据对象

    分布式数据对象是一个JS对象型的封装。每一个分布式数据对象实例会创建一个内存数据库中的数据表,每个应用程序创建的内存数据库相互隔离,对分布式数据对象的“读取”或“赋值”会自动映射到对应数据库的put/get操作。

    分布式数据对象的生命周期包括以下状态:

    • 未初始化:未实例化,或已被销毁。
    • 本地数据对象:已创建对应的数据表,但是还无法进行数据同步。
    • 分布式数据对象:已创建对应的数据表,设备在线且组网内设置同样sessionId的对象数>=2,可以跨设备同步数据。若设备掉线或将sessionId置为空,分布式数据对象退化为本地数据对象。

运作机制

分布式数据对象生长在分布式内存数据库之上,在分布式内存数据库上进行了JS对象型的封装,能像操作本地变量一样操作分布式数据对象,数据的跨设备同步由系统自动完成。

图1 分布式数据对象运行机制

 

约束与限制

  • 不同设备间只有相同bundleName的应用才能直接同步。

  • 不建议创建过多分布式数据对象,每个分布式数据对象将占用100-150KB内存。

  • 每个分布式数据对象大小不超过500KB。

  • 如对复杂类型的数据进行修改,仅支持修改根属性,暂不支持下级属性修改。

  • 支持JS接口间的互通,与其他语言不互通。

场景介绍

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

接口说明

创建数据对象实例

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

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

包名 接口名 描述
ohos.data.distributedDataObject createDistributedObject(source: object): DistributedObject 创建一个分布式数据对象实例,用于数据操作
- source:设置distributedObject的属性。
- DistributedObject:返回值是创建好的分布式对象。

创建分布式数据对象sessionId

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

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

包名 接口名 描述
ohos.data.distributedDataObject genSessionId(): string 创建一个sessionId,可作为分布式数据对象的sessionId。

设置分布式数据对象sessionId

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

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

类名 接口名 描述
DistributedDataObject setSessionId(sessionId?: string): boolean 为分布式数据对象设置sessionId
 sessionId:分布式对象在可信组网中的标识ID。如果要退出分布式组网,设置为""或不设置均可。

订阅数据变更

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

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

类名 接口名 描述
DistributedDataObject on(type: ‘change’, callback: Callback<{ sessionId: string, fields: Array }>): void 订阅数据变更。
DistributedDataObject off(type: ‘change’, callback?: Callback<{ sessionId: string, fields: Array }>): void 注销订阅。需要删除的变更回调,若不设置则删除该对象所有的变更回调。

订阅数据对象上下线

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

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

类名 接口名 描述
DistributedDataObject on(type: ‘status’, callback: Callback): void 订阅数据对象上下线。
DistributedDataObject off(type: ‘status’, callback?: Callback): void 注销订阅。

保存和撤回已保存的数据对象

保存数据对象:数据对象保存成功后,当应用存在时不会释放对象数据;当应用退出后,重新进入应用时,恢复保存在设备上的数据。

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

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

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

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

类名 接口名 描述
DistributedDataObject save(deviceId: string): Promise 保存数据对象。
DistributedDataObject save(deviceId: string, callback: AsyncCallback): void 保存数据对象。
DistributedDataObject revokeSave(callback: AsyncCallback): void 撤回已保存的数据对象。
DistributedDataObject revokeSave(): Promise 撤回已保存的数据对象。

开发步骤

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

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

    import distributedObject from '@ohos.data.distributedDataObject';   
  2. 请求权限。需要在config.json里面进行配置请求权限,示例代码如下:

     {   "module": {"reqPermissions": [    {"name": "ohos.permission.DISTRIBUTED_DATASYNC"    }]   } }

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

    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();
  3. 获取分布式数据对象实例。

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

    var local_object = distributedObject.createDistributedObject({name:undefined, age:undefined, isVis:true,  parent:undefined, list:undefined});var sessionId = distributedObject.genSessionId();
  4. 加入同步组网。同步组网中的数据对象分为发起方和被拉起方。

    以下为加入同步组网的代码示例:

    //发起方var local_object = distributedObject.createDistributedObject({name:"jack", age:18, isVis:true,     parent:{mother:"jack mom",father:"jack Dad"},list:[{mother:"jack mom"}, {father:"jack Dad"}]});local_object.setSessionId(sessionId);//被拉起方var remote_object = distributedObject.createDistributedObject({name:undefined, age:undefined, isVis:true,  parent:undefined, list:undefined});remote_object.setSessionId(sessionId);//收到status上线后remote_object同步数据,即name变成jack,age是18
  5. 监听对象数据变更。可监听对端数据的变更,以callback作为变更回调实例。

    以下为监听对象数据变更的代码示例。

    function changeCallback(sessionId, changeData) {     console.info("change" + sessionId);     if (changeData != null && changeData != undefined) {  changeData.forEach(element => {      console.info("changed !" + element + " " + local_object[element]);     });     } }  // 发起方要在changeCallback里刷新界面,则需要将正确的this绑定给changeCallback local_object.on("change", this.changeCallback.bind(this));
  6. 修改对象属性,对象属性支持基本类型(数字类型、布尔类型、字符串类型)以及复杂类型(数组、基本类型嵌套等)。

    以下为修改分布式数据对象属性的代码示例:

    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"}];

说明:

针对复杂类型的数据修改,目前支持对根属性的修改,暂不支持对下级属性的修改。示例如下:

//支持的修改方式local_object.parent = {mother:"mom", father:"dad"};//不支持的修改方式local_object.parent.mother = "mom";
  1. 访问对象。可以通过直接获取的方式访问到分布式数据对象的属性,且该数据为组网内的最新数据。

    以下为访问对象的代码示例:

    console.info("name " + local_object["name"]); 
  2. 删除监听数据变更。可以指定删除监听的数据变更回调;也可以不指定,这将会删除该分布式数据对象的所有数据变更回调。

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

    //删除变更回调changeCallbacklocal_object.off("change", changeCallback);//删除所有的变更回调local_object.off("change"); 
  3. 监听分布式对象的上下线。可以监听对端分布式数据对象的上下线。
    以下为访问对象的代码示例:

     function statusCallback(sessionId, networkId, status) {   this.response += "status changed " + sessionId + " " + status + " " + networkId; } local_object.on("status", this.statusCallback);
  4. 保存和撤回已保存的数据对象。

    1.callback方式

     // 保存数据对象 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); });

    2.Promise方式

     // 保存数据对象 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."); });
  5. 删除监听分布式对象的上下线。可以指定删除监听的上下线回调;也可以不指定,这将会删除该分布式数据对象的所有上下线回调。

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

    //删除上下线回调statusCallbacklocal_object.off("status", this.statusCallback);//删除所有的上下线回调local_object.off("status");
  6. 退出同步组网。分布式对象退出组网后,本地的数据变更对端不会同步。

    以下为退出同步组网的代码示例:

    local_object.setSessionId("");