HarmonyOS开发实例:【分布式数据管理】

news2024/11/25 4:57:37

介绍

本示例展示了在eTS中分布式数据管理的使用,包括KVManager对象实例的创建和KVStore数据流转的使用。

通过设备管理接口[@ohos.distributedDeviceManager],实现设备之间的kvStore对象的数据传输交互,该对象拥有以下能力 ;
1、注册和解除注册设备上下线变化监听
2、发现周边不可信设备
3、认证和取消认证设备
4、查询可信设备列表
5、查询本地设备信息,包括设备名称,设备类型和设备标识
6、发布设备发现

效果预览

首页

main

使用说明

鸿蒙OS开发更多内容↓点击HarmonyOS与OpenHarmony技术
鸿蒙技术文档开发知识更新库gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md在这。

1.两台设备组网。

2.在一台界面中点击右上角的流转按钮,在弹窗中选择对端设备拉起对端设备上的应用。

3.拉起对端设备后,在界面中点击"+"按钮新增笔记卡片,点击每个卡片右上角的"X"按钮可以删除此卡片,可以看到对端设备和当前设备界面数据保持一致。

4.操作对端设备,当前设备界面也会保持和对端设备界面显示一致。

搜狗高速浏览器截图20240326151450.png

具体实现

管理kvStore

1、页面初始化时获取此应用所需能力:引入@ohos.data.distributedKVStore初始化kvstore数据库并对使用kvstore.on数据change进行监听,通过appstorge判断获取相应的key判断是否是分布式节点 。

源码:

/*

 * Copyright (c) 2020-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import abilityAccessCtrl from '@ohos.abilityAccessCtrl'

import common from '@ohos.app.ability.common'

import { NoteModel } from '../model/NoteDataModel'

import { NoteListItem } from '../common/NoteItem'

import NoteDataSource from '../common/BasicDataSource'

import { TitleBar } from '../common/TitleBar'

import { KvStoreModel } from '../model/KvStoreModel'

import { RemoteDeviceModel } from '../model/RemoteDeviceModel'

import { transStrToNoteModel } from '../model/NoteDataModel'

import Logger from '../util/Logger'

import Want from '@ohos.app.ability.Want';



const NOTES_CHANGE = 'notesChange'

const EXIT = 'exit'

let kvStoreModel: KvStoreModel = new KvStoreModel()

let notesNum: number = 0

const TAG = 'KvstoreIndexPage'



@Entry

@Component

struct Index {

  private noteDataSource: NoteDataSource = new NoteDataSource([new NoteModel('', '')]);

  @State isDistributed: boolean = false

  private remoteDeviceModel: RemoteDeviceModel = new RemoteDeviceModel()



  aboutToAppear() {

    let context = getContext(this) as common.UIAbilityContext

    let atManager = abilityAccessCtrl.createAtManager()

    try {

      atManager.requestPermissionsFromUser(context,['ohos.permission.DISTRIBUTED_DATASYNC']).then((data) => {

        Logger.info(TAG, `data: ${JSON.stringify(data)}`)

      }).catch((err: object) => {

        Logger.info(TAG, `err: ${JSON.stringify(err)}`)

      })

    } catch (err) {

      Logger.info(TAG, `catch err->${JSON.stringify(err)}`);

    }

    let want = JSON.parse(AppStorage.Get('wantMsg')) as Want;

    Logger.info(TAG,`getWant =${JSON.stringify(want)}`);

    if(want.parameters != undefined) {

      if (want.parameters.isStage === 'Stage') {

        this.isDistributed = true

      }

    }

    kvStoreModel.setOnMessageReceivedListener(NOTES_CHANGE, (value) => {

      Logger.info(TAG,`NOTES_CHANGE${value}`)

      if (this.isDistributed) {

        if (value.search(EXIT) !== -1) {

          Logger.info(TAG,`[json]EXIT${EXIT}`)

          context.terminateSelf((error) => {

            Logger.info(TAG,`terminateSelf finished, error=${error}`)

          })

        } else {

          let str: string = value.substring(0, value.lastIndexOf('}]') + 2);

          this.noteDataSource.dataArray = transStrToNoteModel(str);

          this.noteDataSource.notifyDataReload()

          let strNum: string = value.substring(value.lastIndexOf('numBegin') + 'numBegin'.length, value.lastIndexOf('numEnd'));

          notesNum = Number(strNum)

        }

      }

    })

  }



  deleteNoteCallBack = (item: NoteModel) => {

    Logger.info(TAG, `deleteNote${JSON.stringify(item)}`);

    let dataArray: NoteModel[] = this.noteDataSource.dataArray;

    for (let i = 0; i < dataArray.length; i++) {

      Logger.info(TAG, `i = ${i} and dataArray = ${JSON.stringify(dataArray[i])}`)

      if (dataArray[i].title === item.title) {

        Logger.info(TAG, `deleteNote index` + i);

        this.noteDataSource.dataArray.splice(i, 1);

        break

      }

    }

    this.noteDataSource.notifyDataReload()

    kvStoreModel.put(NOTES_CHANGE, JSON.stringify(this.noteDataSource.dataArray) + 'numBegin' + notesNum + 'numEnd');

  }

  startAbilityCallBack = (key: string) => {

    Logger.info(TAG,`startAbilityCallBack${key}`);

    if (NOTES_CHANGE === key) {

      kvStoreModel.put(NOTES_CHANGE, `${JSON.stringify(this.noteDataSource.dataArray)}numBegin${notesNum}numEnd`);

    }

    if (EXIT === key) {

      kvStoreModel.put(NOTES_CHANGE, EXIT)

    }

  }



  build() {

    Column() {

      TitleBar({

        startAbilityCallBack: this.startAbilityCallBack,

        remoteDeviceModel: this.remoteDeviceModel,

        isDistributed: $isDistributed

      })



      Grid() {

        LazyForEach(this.noteDataSource, (item: NoteModel, index) => {

          GridItem() {

            NoteListItem({

              note: item,

              deleteNoteCallBack: this.deleteNoteCallBack,

              noteID: index

            })

          }

          .onClick(() => {

            Logger.info(TAG,`GridItem.click${item.title}`);

            if (item.title === '' && item.content === '') {

              notesNum += 1

              this.noteDataSource.dataArray[this.noteDataSource.dataArray.length-1] = new NoteModel(`note ${notesNum}`, 'noteContent');

              this.noteDataSource.dataArray.push(new NoteModel('', ''));

              this.noteDataSource.notifyDataReload()

              if (this.isDistributed) {

                kvStoreModel.put(NOTES_CHANGE, `${JSON.stringify(this.noteDataSource.dataArray)}numBegin${notesNum}numEnd`);

              }

            }

          })

        }, (item: NoteModel) => item.title)

      }

      .columnsTemplate('1fr 1fr 1fr')

      .columnsGap(10)

      .rowsGap(10)

      .padding(10)

      .margin({ bottom: 50 })

    }

  }



  onDestroy() {

    if (this.remoteDeviceModel !== null) {

      this.remoteDeviceModel.unregisterDeviceListCallback()

    }

    if (this.isDistributed) {

      this.isDistributed = false

    }

  }

}

2、如果是分布式节点,如果数据发生变化,处理数据并使用.noteDataSource()进行reload数据。
3、页面通过kvStore对象进行增删改查会触发其他已连接设备的kvStore.on监听。

管理分布式设备(节点)

1、创建设备管理对象,并指定参数kvstore应用包deviceManager.createDeviceManager("ohos.samples.kvstore", (error, value) => {})
2、获取可信设备列表,"this.deviceManager.getTrustedDeviceListSync())" 。 3、监听设备状态,"this.deviceManager.on('deviceStateChange', (data) => {})",从而对可信设备列表管理。

鸿蒙Next核心技术分享

1、鸿蒙基础知识←《鸿蒙NEXT星河版开发学习文档》

2、鸿蒙ArkUI←《鸿蒙NEXT星河版开发学习文档》

3、鸿蒙进阶技术←《鸿蒙NEXT星河版开发学习文档》

 4、鸿蒙就业高级技能←《鸿蒙NEXT星河版开发学习文档》 

 5、鸿蒙多媒体技术←《鸿蒙NEXT星河版开发学习文档》 

6、鸿蒙南向驱动开发←《鸿蒙NEXT星河版开发学习文档》  

7、鸿蒙南向内核设备开发←《鸿蒙NEXT星河版开发学习文档》  

 8、鸿蒙系统裁剪与移植←《鸿蒙NEXT星河版开发学习文档》  

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot菜品分页查询模块开发(多表连接查询)

需要注意的地方 为什么创建VO类怎么进行多表连接查询分页查询的统一返回结果类PageResult分页查询Mapper的返回结果是Page<目标实体类> 需求分析与设计 一&#xff1a;产品原型 系统中的菜品数据很多的时候&#xff0c;如果在一个页面中全部展示出来会显得比较乱&…

力扣HOT100 - 238. 除自身以外数组的乘积

解题思路&#xff1a; 当前位置的结果就是它左部分的乘积再乘以它右部分的乘积。因此需要进行两次遍历&#xff0c;第一次遍历用于求左部分的乘积&#xff0c;第二次遍历在求右部分的乘积的同时&#xff0c;再将最后的计算结果一起求出来。 class Solution {public int[] prod…

Transformer详解和知识点总结

目录 1. 注意力机制1.1 注意力评分函数1.2 多头注意力&#xff08;Multi-head self-attention&#xff09; 2. Layer norm3. 模型结构4. Attention在Transformer中三种形式的应用 论文&#xff1a;https://arxiv.org/abs/1706.03762 李沐B站视频&#xff1a;https://www.bilibi…

(学习日记)2024.04.05:UCOSIII第三十三节:互斥量

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

SpringBoot第一个hello world项目

文章目录 前言一、Spring Boot是什么&#xff1f;二、使用步骤1. 创建项目2.书写测试 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了…

DRL-VWAP算法

摘要 在量化策略的交易端&#xff0c;为了更好的扩大策略的资金容量必须要考虑策略冲击陈本的降低。本文梳理了传统 VWAP 存在的诸多弊端&#xff0c;主要在于对于日内交易信息的缺失与忽略市场行情的影响。本文梳理了传统VWAP 算法存在的主要弊端&#xff0c;并改写了传统 VW…

20240409在全志H3平台的Nano Pi NEO CORE开发板运行的Ubuntu Core更新boot.img(eMMC启动)

20240409在全志H3平台的Nano Pi NEO CORE开发板运行的Ubuntu Core更新zImage内核 2024/4/9 9:21 一、生成zImage: 参考资料&#xff1a; http://wiki.friendlyelec.com/wiki/index.php/NanoPi_NEO_Core/zh#.E7.83.A7.E5.86.99.E5.88.B0eMMC NanoPi NEO Core/zh 6 FriendlyCore…

【leetcode面试经典150题】37. 矩阵置零(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

大数据相关组件安装及使用

自学大数据相关组件 持续更新中。。。 一、linux安装docker 1、更新yum sudo yum update2、卸载docker旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine3、…

菜鸟IPO折戟背后:估值大幅下降,阿里巴巴为“分拆之痛”买单

撰稿|行星 来源|贝多财经 近日&#xff0c;阿里巴巴集团&#xff08;下称“阿里巴巴”或“阿里”&#xff09;发布公告&#xff0c;称其物流子公司菜鸟&#xff08;同菜鸟物流、菜鸟网络&#xff09;撤回在港交所的首次公开发行及上市申请&#xff0c;并计划收购菜鸟少数股东…

LeetCode31. 下一个排列(Java)

题目&#xff1a; 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列…

鸿蒙实战开发-如何实现查看系统相册、最近删除、收藏夹操作功能

介绍 本示例主要展示了相册相关的功能&#xff0c;使用ohos.file.photoAccessHelper 接口&#xff0c;实现了查看系统相册、创建用户相册、查看相册照片、用户相册文件添加和删除、以及预览图片、最近删除、收藏夹操作等功能; 效果预览 使用说明 主界面&#xff1a;查询显示…

一本想教会你滤波算法书

一本想教会你滤波算法书 从今天开始&#xff0c;这个博客系列会翻译一本 500 页左右的滤波算法的书&#xff0c;该书的原文连接我会放到后面的文中。翻译这本书不仅能继续我的英语学习&#xff08;水平有限&#xff0c;有问题我留言我马上改&#xff01;&#xff09;而且可以跟…

如何合理利用Vue 3中的ref和reactive

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

大话设计模式——24.迭代器模式(Iterator Pattern)

简介 提供一种方法顺序访问一个聚合对象中各个元素&#xff0c;而又不暴露该对象的内部实现。&#xff08;Java中使用最多的设计模式之一&#xff09; UML图 应用场景 Java的集合对象&#xff1a;Collection、List、Map、Set等都有迭代器Java ArrayList的迭代器源码 示例 简…

堆 和 优先级队列

目录 一、堆 二、优先级队列 1、初识优先级队列 2、实现一个优先级队列 3、PriorityQueue &#xff08;1&#xff09;实现了Comparable接口&#xff0c;重写了compareTo方法 &#xff08;2&#xff09;实现了Comparator接口&#xff0c;重写了compare方法 4、 Prio…

WordPress 图片压缩插件:Compress JPEG PNG images 使用方法

插件介绍 Compress JPEG & PNG images是一款非常好用的图片压缩插件:&#xff0c;非常值得大家安装使用&#xff1b;特别是图片类型网站。其实我们很多服务器磁盘空间是不在乎多那么几十 MB 大小的&#xff0c;但是压缩了图片能提升网站速度&#xff0c;节省宽带&#xff…

Linux网络名称空间之独立网络资源管理

Linux网络名称空间是一种强大的虚拟化技术&#x1f6e0;️&#xff0c;它允许用户创建隔离的网络环境&#x1f310;&#xff0c;每个环境拥有独立的网络资源和配置。这项技术对于云计算☁️、容器化应用&#x1f4e6;和网络安全&#x1f512;等领域至关重要。本文将详细介绍在L…

python如何写入csv

在使用python对文件操作的过程中&#xff0c;你肯定碰到过对csv文件的操作&#xff0c;下面就python对csv文件的操作进行详述。 CSV&#xff08;Comma-Separated Values&#xff09;逗号分隔符&#xff0c;也就是每条记录中的值与值之间是用分号分隔的。 打开CSV文件并写入一…

第36篇:分频器<三>

Q&#xff1a;这一期我们介绍以计数器方式实现四分频的概念原理。 A&#xff1a;计数器分频有分频系数和占空比这两个参数。待分频时钟的频率为f1&#xff0c;分频后时钟的频率为f2&#xff0c;分频系数为Nf1/f2。 计数器分频电路通过对时钟信号计数来实现分频。根据分频系数可…