鸿蒙原生应用开发【分布式数据对象】

01、什么是分布式数据对象

在可信组网环境下,多个相互组网认证的设备将各自创建的对象加入同一个 sessionId,使得加入的多个数据对象之间可以同步数据,也就是说,当某一数据对象属性发生变更时,其他数据对象会检测到这一变更,同时将自身属性更新。此时,该 sessionId 下的所有数据对象属性相同,这样的数据对象称之为分布式数据对象。此外,分布式数据对象可以被动退出 sessionId,当分布式数据对象退出 sessionId 后,该对象将检测不到其他对象的变更。

02、分布式数据对象能力

1、 分布式数据对象创建
2、 分布式数据对象查询
3、 分布式数据对象修改
4、 分布式数据对象删除
5、 分布式数据对象保存
6、 分布式数据对象订阅(数据变更,上下线)
7、分布式数据对象加入、退出分布式组网

03、前提准备

1、 开发工具:DevEco Studio 3.1.0.501
2、API:9
3、 SDK 版本:3.2.12.5

04、创建一个新的项目

新建项目,选择 API9 版本,stage 模型。

05、权限申请

1、 使用到的权限

○ ohos.permission.DISTRIBUTED_DATASYNC

○ 允许不同设备间的数据交换

○ 权限级别:normal

○ 授权方式:user_grant

○ ACL 使能:TRUE

2、配置文件申明

首先,在项目的模块级目录下找到并打开 module.json5 文件,如下图:

在 module 下的对象里添加如下申明:

此时,配置文件中的权限申明就完成了,但是,此时我们还不能获得这些权限。由于 ohos.permission.DISTRIBUTED_DATASYNC 权限是 ACL 使能为 TRUE 的权限,需要在签名工具文件中说明一下。

如何找到对应的签名工具文件呢?我们在安装 DevEco Studio 的时候是下载好了 OpenHarmony 的 SDK 的,此时在 OpenHarmony 文件夹中,打开 “Sdk\OpenHarmony SDK 版本\toolchains\lib” 该路径,此时在 lib 文件夹中,咱们可以找到两个 json 文件,分别为 UnsgnedDebugProfileTemplate.json 和 UnsgnedReleasedProfileTemplate.json,点击并打开这两个文件,添加如下权限:

3、权限申请编码

在申请 ohos.permission.DISTRIBUTED_DATASYNC 权限时,其文档中将其标注为用户手动授权的权限,此时需要我们动态申请权限,在项目中,我们新建一个 ets 文件,我这里取名为 RequestPermission.ets。

首先,导入以下包:

import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import bundleManager from '@ohos.bundle.bundleManager';
import common from '@ohos.app.ability.common';

获取访问控制模块对象实例:

let atManager = abilityAccessCtrl.createAtManager();

编写如下方法(这里使用的是异步函数):

export async function checkAccessTokenID(permission: Array<Permissions>) {// 获取应用程序的accessTokenIDlet tokenId: number;let grantStatus: Array<abilityAccessCtrl.GrantStatus> = []try {let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;tokenId = appInfo.accessTokenId;} catch (err) {console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`);}// 校验应用是否被授予权限,若申请多个权限,建议循环检查多个权限for (let index = 0;index < permission.length; index++) {try {grantStatus.push(await atManager.checkAccessToken(tokenId, permission[index]))} catch (err) {console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`);}}return grantStatus;
}export async function checkPermission(context: common.UIAbilityContext, permissions: Array<Permissions>) {let grantStatus: Array<abilityAccessCtrl.GrantStatus> = await checkAccessTokenID(permissions)for (let i = 0; i < grantStatus.length; i++) {if (grantStatus[i] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {console.info(`${permissions[i].toString()} 已授权`)} else {//申请权限console.info('开始向用户申请权限')requestPermissionFromUser(context, permissions)}}
}
export async function requestPermissionFromUser(context: common.UIAbilityContext, permissions: Array<Permissions>) {// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗atManager.requestPermissionsFromUser(context, permissions).then((data) => {let grantStatus: Array<number> = data.authResultslet length: number = grantStatus.lengthfor (let i = 0;i < length; i++) {if (grantStatus[i] === 0) {// 用户授权,可以继续访问目标操作console.info(`${permissions[i].toString()} 权限申请成功`)} else {// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限console.info(`${permissions[i].toString()} 权限申请被用户拒绝`)}}// 授权成功})
}

此时,我们申请权限的方法就算编写完成了,在应用入口,即 EntryAbility.ts 文件中的

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam)

方法中回调权限申请函数:

requestPermissionFromUser(this.context, PERMISSIONS)

其中,PERMISSIONS 定义如下:const PERMISSIONS:Array=[‘ohos.permission.DISTRIBUTED_DATASYNC’]

到此,我们的权限申请就算完完全全完成啦,当用户第一次安装并打开应用的时候,应用会向用户通过弹窗形式申请权限,用户点击授权即可赋予应用相应的权限啦~

06、上手分布式数据对象代码开发

登录了同一华为帐号的 HarmonyOS 设备已经默认了进行了组网认证,所以在进行分布式数据对象开发之前无需再进行多设备组网认证这一阶段的开发,开发变得相对简单了起来。首先,咱们制作一个简易 UI 界面(UI 界面仅供参考),如下图所示:

相信对于有 HarmonyOS 开发经验的小伙伴们来说这样的 UI 界面制作并不困难,其中红色圆点、绿色圆点为设备状态,当设备状态发生改变如下线时,颜色变为红色,UI 界面代码如下:

import router from '@ohos.router'
import { DistributedDeviceManageFunc } from '../modules/DistributedDeviceManager/DistributedDeviceManagerFunctions'
import DistributedObjectFunc from '../modules/DistributedObject/DistributedObjectFunctions'
import { ContinuationDeviceManagerDialog } from '../view/ContinuationDeviceManagerDialog'
import { DistributedDeviceManagerDialog } from '../view/DistributedDeviceManagerDialog'AppStorage.SetOrCreate('distributedDeviceList', [])
AppStorage.SetOrCreate('message', '分布式数据对象Demo测试')
AppStorage.SetOrCreate('statusColor', '#ff4fc100')
AppStorage.SetOrCreate('distributedColor', '#ffff0000')@Entry
@Component
struct DistributedObjectDemo {@StorageLink('message') message: string = ''@StorageLink('statusColor') statusColor: string = ''@StorageLink('distributedColor') distributedColor: string = ''@StorageLink('distributedObj') distributedObj: DistributedObjectFunc = new DistributedObjectFunc()@BuildernavigationTitle() {Row({ space: '10vp' }) {Button({ type: ButtonType.Normal }) {Image($rawfile('ic_public_back.svg')).size({width: '24vp',height: '24vp'})}.width('36vp').height('36vp').backgroundColor(Color.White).borderRadius('10vp').onClick(() => {DistributedDeviceManageFunc.release()router.back()})Text('分布式数据对象测试').fontWeight(FontWeight.Bold).fontSize('20vp')Blank()Button({ type: ButtonType.Normal }) {Image($rawfile('ic_public_connection_filled.svg')).size({width: '24vp',height: '24vp'})}.width('36vp').height('36vp').backgroundColor(Color.White).borderRadius('10vp').onClick(() => {this.distributedDeviceManagerDialogController.open()})}.padding('5vp').width('90%')}build() {Navigation() {Column({ space: '20vp' }) {Row({ space: '20vp' }) {Text(`设备状态`).fontSize('20vp').fontWeight(FontWeight.Bold)Circle().width('25vp').height('25vp').fill(this.statusColor)}Row({ space: '20vp' }) {Text(`对端设备状态`).fontSize('20vp').fontWeight(FontWeight.Bold)Circle().width('25vp').height('25vp').fill(this.distributedColor)}Text(`SessionID:${this.distributedObj.getSessionId()}`).fontSize('20vp').fontWeight(FontWeight.Bold)Text(this.message).fontSize('20vp').fontWeight(FontWeight.Bold).maxLines(2)Button('保存分布式数据对象').buttonStyles().onClick(() => {this.distributedObj.saveDistributedObject()})Button('修改分布式数据对象').buttonStyles().onClick(() => {this.distributedObj.updateDistributedObject()})Button('退出组网').buttonStyles().onClick(() => {this.distributedObj.exit()router.back()})}.width('100%')}.width('100%').height('100%').mode(NavigationMode.Auto).titleMode(NavigationTitleMode.Mini).hideBackButton(true).title(this.navigationTitle())}
}@Extend(Button) function buttonStyles() {.fontSize('20vp').width('60%').height('50vp')
}

现在,我们的页面制作就完成啦,下面开始重头戏——分布式数据对象开发流程

1、导入模块

import distributedObject from '@ohos.data.distributedDataObject'

2、初始化 distributedObject. DataObject 对象

定义一个 distributedObject. DataObject 类型的变量。

mDistributedObject: distributedObject.DataObject

调用 distributedObject. Create()函数创建一个 distributedObject. DataObject 对象,并将其返回给定义的变量 mDistributedObject。

this.mDistributedObject = distributedObject.create(globalThis.context, {name: 'jack',age: 18,isVis: false
})

在 create()方法中存在两个参数,context 和 resource,context 的类型为 Context,resource 类型为 object,在这里我是在 entryAbility.ts 文件下的 onWindowStageCreate()方法里面定义了一个全局变量 globalThis.context。

globalThis.context = this.context

3、设置组网 sessionId

this.mDistributedObject.setSessionId(this.mSessionId)

在 setSessionId()函数中,参数 sessionId 为 string 类型,表示分布式对象组网唯一标识符,设置同步的 sessionId,当可信组网中有多个设备时,多个设备间的对象如果设置为同一个 sessionId,就能自动同步。

4、开启设备状态监听

globalThis.statusCallback = (sessionId: string, networkId: string, status: string) => {AppStorage.Set('message', `组网设备状况变更,id:${sessionId} status:${status} networkId:${networkId}`)if (status == 'online') {AppStorage.Set('distributedColor', '#ff4fc100')} else if (status == 'offline') {AppStorage.Set('distributedColor', '#ffff0000')}
}
this.mDistributedObject.on("status", globalThis.statusCallback)

(sessionId: string, networkId: string, status: string)为 callback 回调函数返回的值,我们可以使用这些返回值判断设备上下线状态,其中 status 参数返回值为 online 或者 offline,表示设备对端设备上下线。

5、开启分布式数据对象同步监听

globalThis.changeCallback = (sessionId: string, fields: Array<string>) => {console.info('分布式数据对象发生变化')if (fields != null && fields != undefined) {AppStorage.Set('message', `data change:${fields} sessionId:${sessionId}`)}
}
this.mDistributedObject.on("change", globalThis.changeCallback)

当同一组网内分布式数据对象发生改变时,同一组网中的所有分布式数据对象同步发生变化,变化后的值为某一分布式数据对象改变后的值(sessionId: string, fields: Array)为 callback 回调函数返回值,其中,sessionId 为组网唯一标识符,field 为分布式数据对象的数据变更列表。

此时此刻,分布式数据对象就基本上开发完成啦。

如果有小伙伴想要修改分布式数据对象的属性,可以直接修改

// @ts-ignore
this.mDistributedObject.name = 'lucy'
// @ts-ignore
this.mDistributedObject.age = 25

注意:根据当前版本 IDE 的编码插件情况,不能直接写 this.mDistributedObject.age = 25,此时咱们需要加上// @ts-ignore 就可以啦。

最后,使用完分布式数据对象后大家要记得释放资源哦(注销所有监听,退出组网 sessionId,将分布式数据对象设置为空值)

this.mDistributedObject.off("change")
this.mDistributedObject.off("status")
this.mDistributedObject.setSessionId()
this.mDistributedObject = null
this.mSessionId = null

如果有小伙伴有两部或两部以上的华为设备,可以将程序烧录到设备中,体验一下分布式数据对象能力的快乐~

为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙 (Harmony OS)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. 应用开发导读(Java)

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/257947.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优秀软件测试工程师必备的“8个能力”

首先要说&#xff0c;做软件测试不难&#xff0c;难的是做好软件测试。 结合自己这些年的工作经验&#xff0c;自己也总结出来8个方面的能力&#xff0c;可能有些方面感觉要求暂时还达不到&#xff0c;但这些确实是做软件测试工作所必备的能力&#xff0c;掌握了这8个方面的能力…

Mybatis XML改查操作(结合上文)

"改"操作 先在UserInfoXMLMapper.xml 中 : <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><map…

vue使用甘特图dhtmlxgantt + gantt.addTaskLayer

效果图&#xff1a; 甘特图 官网地址 gantt安装与使用 vue版---部分功能收费 安装gantt 或 引入文件 npm install dhtmlx-gantt -save或import gantt from "/public/static/dhtmlxgantt/dhtmlxgantt.js"; import "/public/static/dhtmlxgantt/locale/local…

【银行测试】金融项目+测试方法范围分析,功能/接口/性能/安全...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、金融行业软件特…

spring-boot-starter-validation是什么Validation参数校验使用概要

spring-boot-starter-validation是什么&Validation参数校验使用概要 来源Valid和Validated的用法(区别)引入依赖Valid和Validated的用法 在日常的项目开发中&#xff0c;为了防止非法参数对业务造成的影响&#xff0c;需要对接口的参数做合法性校验&#xff0c;例如在创建用…

【面试经典150 | 二叉树】从前序与中序遍历序列构造二叉树

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;递归 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容…

远程调试Linux服务器上的代码

远程调试Linux服务器上的代码 首先我们的环境有本地环境还有研发环境&#xff0c;本地环境就是我们本地电脑上面的代码&#xff0c;而研发环境就是我们开发好一个功能&#xff0c;发到一个linux服务器上面的代码&#xff1b;但是有些时候&#xff0c;研发环境上面的代码可能会…

构造,析构,拷贝构造

1. 类的6个默认的成员变量 如果一个类中什么成员都没有,简称为空类,空类中什么都没有&#xff1f;并不是的,任何一个类在我们不写的情况下,都会自动生成下面6个默认成员函数。 注意&#xff1a;这里的“默认”和“缺省”的意思差不多&#xff0c;也就是你不写这6个函数&#…

Flask template+Vue +项目中include引入其他模版(其他模版也会用到vue)的使用探索

项目背景是&#xff1a;团队的历史项目&#xff0c;是flask tmeplate写的前段页面。然后我在一个页面A.html中引入了vue文件&#xff0c;使用了vueelement_ui技术。现在想在此A页面中插入另外一个页面B.html的内容&#xff08;试图tab分开&#xff09;&#xff0c;因为入口只有…

No suitable driver found for jdbc:mysql://localhost:3306(2023/12/7更新)

有两种情况&#xff1a; 压根没安装下载了但没设为库或方法不对 大多数为第一种情况&#xff1a; 一. 下载jdbc 打开网址选择一个版本进行下载 https://nowjava.com/jar/version/mysql/mysql-connector-java.html 二.安装jdbc 在项目里建一个lib文件夹 在把之前下载的jar文…

免费的数据采集软件,最新免费的几款数据采集软件【2024】

在当今数字化时代&#xff0c;数据是企业决策和业务发展的关键。而如何高效获取数据成为许多企业和研究机构的关注焦点。本文将深入探讨数据采集软件的种类。帮助大家选择最适合自己需求的数据采集工具。 数据采集软件种类 在众多数据采集软件中&#xff0c;有一类强大而多样…

《一念关山》热度破万,爱奇艺古装赛道出尽风头

​刘诗诗重回古装剧、新式武侠公路片、质感细腻的镜头美学......看点满满的《一念关山》频频登上热搜&#xff0c;俘获了大批观众的心。 开播首日热度就刷新了爱奇艺2023年站内纪录&#xff0c;《一念关山》作为2023年爱奇艺在古装赛道的收官之作&#xff0c;口碑和热度兼收。…