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

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>) {
  // 获取应用程序的accessTokenID
  let 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.authResults
    let length: number = grantStatus.length
    for (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()




  @Builder
  navigationTitle() {
    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. ……

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis 命令全解析之 Hash类型

文章目录 ⛄介绍⛄命令⛄RedisTemplate API⛄应用场景 ⛄介绍 Hash类型&#xff0c;也叫散列&#xff0c;其value是一个无序字典&#xff0c;类似于Java中的 HashMap 结构。 String结构是将对象序列化为JSON字符串后存储&#xff0c;当需要修改对象某个字段时很不方便&#xf…

Navicat 技术指引 | 适用于 GaussDB 分布式的自动运行功能

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…

Nginx按指定格式记录访问日志

今天突然想起来一个日志的一个东西,因为拉项目无意中看到了日志文件的一些东西,现在不经常做后端了,加上其他的一些原因吧.有时候有些问题也没想太多,马马虎虎就过了,后来想想还是要记录一下这方面的处理过程吧: 一般我们作为开发人员关注的日志只是在应用程序层面的,我们称它…

51 单片机定时器

51 单片机定时器 目录 51 单片机定时器定时器作用定时器的工作模式模式1(常用)定时器时钟源中断系统定时器寄存器 补充实际使用 声明&#xff1a;本文以 STC89C52 单片机为例 定时器作用 主要有三个作用 1、用于计时系统&#xff0c;可实现软件计时&#xff0c;使程序每隔一段…

java:slf4j、log4j、log4j2、logback日志框架的区别与示例

文章目录 背景SLF4J - 简单日志门面:Log4j - 强大而古老的日志框架:Log4j2 - Log4j的升级版:Logback - Log4j的继任者:比较Springboot集成slf4j、log4j2参考 背景 在Java开发中&#xff0c;日志记录是一个不可或缺的组成部分。为了满足不同的需求&#xff0c;Java社区涌现出多…

Python---继承

1、什么是继承 我们接下来来聊聊Python代码中的“继承”&#xff1a;类是用来描述现实世界中同一组事务的共有特性的抽象模型&#xff0c;但是类也有上下级和范围之分&#xff0c;比如&#xff1a;生物 > 动物 > 哺乳动物 > 灵长型动物 > 人类 > 黄种人 从哲学…

Navicat 技术指引 | 适用于 GaussDB 分布式的模型功能

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…

UG NX二次开发(C#)-求曲线在某一点处的法矢和切矢

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、在UG NX中创建一个曲线3、直接放代码4、测试案例1、前言 最近确实有点忙了,好久没更新博客了。今天恰好有时间,就更新下,还请家人们见谅。 今天我们讲一下如何获取一条曲线上某一条曲…

9大高效的前端测试工具与框架!

在每个Web应用程序中&#xff0c;作为用户直接可见的应用程序外观&#xff0c;“前端”包括&#xff1a;图形化的用户界面、相应的功能、及其整体站点的可用性。我们可以毫不夸张地说&#xff1a;如果前端无法正常工作&#xff0c;您将无法“拉新”网站的潜在用户。这也正是我们…

VUE+webrtc-streamer 实现实时视频播放(监控设备-rtsp)

效果 下图则启动成功&#xff0c;此时在浏览器访问127.0.0.1:8000可以看到本机监控画面 1、下载webrtc-streamer 地址&#xff1a;https://github.com/mpromonet/webrtc-streamer/releases 2、解压下载包 3、双击webrtc-streamer.exe启动服务 4、将下载包html文件夹下webrt…

MySQL数据库sql语句操作

一、数据库模型 关系型数据库是一种以表格形式组织和存储数据的数据库。它使用关系模型&#xff0c;其中数据被组织为多个表格&#xff0c;每个表格包含了多个行和列。每个表格的列描述了数据的属性&#xff0c;而行包含了实际的数据记录。 非关系型数据库&#xff0c;也称为…

【ChatGLM3】第三代大语言模型多GPU部署指南

关于ChatGLM3 ChatGLM3是智谱AI与清华大学KEG实验室联合发布的新一代对话预训练模型。在第二代ChatGLM的基础之上&#xff0c; 更强大的基础模型&#xff1a; ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用了更多样的训练数据、更充分的训练步数和更合理的训练策略。在语义、…

HttpComponents: 领域对象的设计

1. HTTP协议 1.1 HTTP请求 HTTP请求由请求头、请求体两部分组成&#xff0c;请求头又分为请求行(request line)和普通的请求头组成。通过浏览器的开发者工具&#xff0c;我们能查看请求和响应的详情。 下面是一个HTTP请求发送的完整内容。 POST https://track.abc.com/v4/tr…

JFlash烧写单片机bin/hex文件

1&#xff0c;安装压 JLink_Windows_V660c&#xff0c;官网可下载&#xff1b; 2&#xff0c;打开刚刚安装的 J-Flash V6.60c 选择创建新工程“Create a new project”&#xff0c;然后点击StartJ-Flash 点击之后跳出Select device框&#xff0c;选择TI 选择TI后&#xff0c…

SpringBoot 项目将jar 部署在服务器引用外部 配置文件

SpringBoot 官方给出了四种方式引用外部配置文件的方式 在jar包的同一目录下建一个config文件夹&#xff0c;然后把配置文件放到这个文件夹下(最常用)直接把配置文件放到jar包的同级目录在classpath下建一个config文件夹&#xff0c;然后把配置文件放进去在classpath下直接放配…

git操作:使用vscode集成

git操作方式 其实git操作一般有三种方式 分别是终端命令行,开发工具集成,专业的git可视化工具 我前面几章说的都是git的命令行操作,今天这篇文章主要是针对开发工具vscode集成git操作进行演示 说明一下,这里之所以选择vscode,是因为本人用的就是vscode,每个开发工具基本都有…

JAVA实现敏感词高亮或打码过滤:sensitive-word

练手项目中实现发表文章时检测文章是否带有敏感词&#xff0c;以及对所有敏感词的一键过滤功能 文章目录 效果预览实现步骤 效果预览 随便复制一篇内容到输入框 机器审核文章存在敏感词&#xff0c;弹消息提示并进入人工审核阶段&#xff08;若机器审核通过&#xff0c;则无需审…

MATLAB基础运算

矩阵和数字相乘 就是矩阵里面每个元素跟这个数字乘一遍 矩阵和矩阵相乘 能不能相乘&#xff0c;需要前面矩阵的列数等于后面矩阵的行数&#xff0c;出来的矩阵大小是前面矩阵的行数*后面矩阵的列数。 所以大家会发现&#xff0c;矩阵相乘如果前后调转了&#xff0c;结果会完全…

STM32的BKP与RTC简介

芯片的供电引脚 引脚表橙色的是芯片的供电引脚&#xff0c;其中VSS/VDD是芯片内部数字部分的供电&#xff0c;VSSA/VDDA是芯片内部模拟部分的供电&#xff0c;这4组以VDD开头的供电都是系统的主电源&#xff0c;正常使用时&#xff0c;全部都要接3.3V的电源上&#xff0c;VBAT是…

无人机巡检中台揭秘,无人机管控平台助力巡查无人机巡检方案落地

随着无人机智能巡检的飞速发展&#xff0c;巡查无人机应用场景也日益多元&#xff0c;无人机巡检方案被频繁落地到工业生产及巡检巡逻业务中。而无人机管控平台应运而生&#xff0c;成为推动无人机智能巡检的关键工具。那我们一起来看一下无人机管控平台的作用&#xff1a; 一、…