0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于鸿蒙分布式数据服务开发的聊天室应用

OpenHarmony威廉希尔官方网站 社区 来源:HarmonyOS威廉希尔官方网站 社区 作者:梁青松 2021-12-03 10:35 次阅读

之前给大家介绍过《HarmonyOS 分布式之仿抖音应用》,此次给大家介绍一下基于鸿蒙分布式数据服务开发的聊天室应用,interwetten与威廉的赔率体系 现实中的聊天室对话,可以与小伙伴们互动、分享自己的故事给小伙伴。

主要知识点

分布式数据服务

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-mdds-guidelines-0000000000030122

官方介绍:分布式数据服务主要实现用户设备中应用程序的数据内容的分布式同步。

当设备 1 上的应用 A 在分布式数据库中增、删、改数据后,设备 2 上的应用 A 也可以获取到该数据库变化,总结一句话:多个设备共用一个数据库。

主页代码

没有特别复杂的逻辑,主要是分布式数据服务的使用,关键地方都有注释。
importcom.ldd.myapp.bean.ChatDataBean;
importcom.ldd.myapp.provider.ChatProvider;
importcom.ldd.myapp.util.Tools;
importohos.aafwk.ability.AbilitySlice;
importohos.aafwk.content.Intent;
importohos.agp.components.Button;
importohos.agp.components.ListContainer;
importohos.agp.components.TextField;
importohos.app.Context;
importohos.bundle.IBundleManager;
importohos.data.distributed.common.*;
importohos.data.distributed.user.SingleKvStore;
importohos.utils.zson.ZSONArray;
importohos.utils.zson.ZSONObject;

importjava.util.ArrayList;
importjava.util.List;

importstaticohos.security.SystemPermission.DISTRIBUTED_DATASYNC;

/**
*主页
*/
publicclassMainAbilitySliceextendsAbilitySlice{
privateContextmContext;
//聊天列表
privateListContainerlcList;
//聊天数据
privatefinalListlistData=newArrayList<>();
//聊天数据适配器
privateChatProviderchatProvider;
//输入框
privateTextFieldtfContent;
//发送按钮
privateButtonbtnSend;

//分布式数据库管理器
privateKvManagerkvManager;
//分布式数据库
privateSingleKvStoresingleKvStore;
//数据库名称
privatestaticfinalStringSTORE_NAME="ChatStore";
//存入的列表数据key
privatestaticfinalStringKEY_DATA="key_data";
//存入的头像索引
privatestaticfinalStringKEY_PIC_INDEX="key_pic_index";
privateintpicIndex=0;

@Override
publicvoidonStart(Intentintent){
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
mContext=this;
requestPermission();
initComponent();
initDatabase();
}

/**
*请求分布式权限
*/
privatevoidrequestPermission(){
if(verifySelfPermission(DISTRIBUTED_DATASYNC)!=IBundleManager.PERMISSION_GRANTED){
if(canRequestPermission(DISTRIBUTED_DATASYNC)){
requestPermissionsFromUser(newString[]{DISTRIBUTED_DATASYNC},0);
}
}
}

/**
*初始化组件
*/
privatevoidinitComponent(){
lcList=(ListContainer)findComponentById(ResourceTable.Id_lc_list);
tfContent=(TextField)findComponentById(ResourceTable.Id_tf_content);
tfContent.setAdjustInputPanel(true);
btnSend=(Button)findComponentById(ResourceTable.Id_btn_send);
btnSend.setEnabled(false);

//初始化适配器
chatProvider=newChatProvider(mContext,listData);
lcList.setItemProvider(chatProvider);

//输入框内容变化监听
tfContent.addTextObserver((text,start,before,count)->{
btnSend.setEnabled(text.length()!=0);
});
//点击发送按钮
btnSend.setClickedListener(component->{
Stringcontent=tfContent.getText().trim();
listData.add(newChatDataBean(Tools.getDeviceId(mContext),picIndex,content));
//存入数据库中
singleKvStore.putString(KEY_DATA,ZSONObject.toZSONString(listData));

//清空输入框
tfContent.setText("");
});
}

/**
*初始化分布式数据库
*/
privatevoidinitDatabase(){
//创建分布式数据库管理器
kvManager=KvManagerFactory.getInstance().createKvManager(newKvManagerConfig(this));

//数据库配置
Optionsoptions=newOptions();
options.setCreateIfMissing(true)//设置数据库不存在时是否创建
.setEncrypt(false)//设置数据库是否加密
.setKvStoreType(KvStoreType.SINGLE_VERSION);//数据库类型
//创建分布式数据库
singleKvStore=kvManager.getKvStore(options,STORE_NAME);
//监听数据库数据改变
singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL,newKvStoreObserver(){
@Override
publicvoidonChange(ChangeNotificationchangeNotification){
ListinsertEntries=changeNotification.getInsertEntries();
ListupdateEntries=changeNotification.getUpdateEntries();

//第一次存入数据,获取insertEntries
if(insertEntries.size()>0){
for(Entryentry:insertEntries){
if(KEY_DATA.equals(entry.getKey())){
//回调为非UI线程,需要在UI线程更新UI
getUITaskDispatcher().syncDispatch(()->{
listData.clear();
listData.addAll(ZSONArray.stringToClassList(entry.getValue().getString(),ChatDataBean.class));
chatProvider.notifyDataChanged();
lcList.scrollTo(listData.size()-1);
});
}
}
}elseif(updateEntries.size()>0){
for(Entryentry:updateEntries){
if(KEY_DATA.equals(entry.getKey())){
//回调为非UI线程,需要在UI线程更新UI
getUITaskDispatcher().syncDispatch(()->{
listData.clear();
listData.addAll(ZSONArray.stringToClassList(entry.getValue().getString(),ChatDataBean.class));
chatProvider.notifyDataChanged();
lcList.scrollTo(listData.size()-1);
});
}
}
}
}
});

try{
picIndex=singleKvStore.getInt(KEY_PIC_INDEX);
singleKvStore.putInt(KEY_PIC_INDEX,picIndex+1);
}catch(KvStoreExceptione){
e.printStackTrace();
//没有找到,首次进入
if(e.getKvStoreErrorCode()==KvStoreErrorCode.KEY_NOT_FOUND){
picIndex=0;
singleKvStore.putInt(KEY_PIC_INDEX,picIndex+1);
}
}
}

@Override
protectedvoidonStop(){
super.onStop();
kvManager.closeKvStore(singleKvStore);
}
}

简单案例

config.json 配置:
"reqPermissions":[
{
"reason":"多设备协同",
"name":"ohos.permission.DISTRIBUTED_DATASYNC",
"usedScene":{
"ability":[
"MainAbility"
],
"when":"always"
}
},
{
"name":"ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
},
{
"name":"ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
},
{
"name":"ohos.permission.GET_BUNDLE_INFO"
}
]

布局页面:

<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">

<Text
ohos:id="$+id:text"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="数据:0"
ohos:text_size="15fp"/>

<Button
ohos:margin="20vp"
ohos:id="$+id:button"
ohos:height="match_content"
ohos:width="match_parent"
ohos:background_element="$graphic:button_bg"
ohos:padding="10vp"
ohos:text="点击+1"
ohos:text_color="white"
ohos:text_size="15fp"/>

DirectionalLayout>
MainAbilitySlice 代码:
importohos.aafwk.ability.AbilitySlice;
importohos.aafwk.content.Intent;
importohos.agp.components.Button;
importohos.agp.components.ListContainer;
importohos.agp.components.Text;
importohos.agp.components.TextField;
importohos.bundle.IBundleManager;
importohos.data.distributed.common.*;
importohos.data.distributed.user.SingleKvStore;
importohos.utils.zson.ZSONArray;

importjava.util.List;

importstaticohos.security.SystemPermission.DISTRIBUTED_DATASYNC;

publicclassMainAbilitySliceextendsAbilitySlice{
//显示数据
privateTexttext;
//分布式数据库管理器
privateKvManagerkvManager;
//分布式数据库
privateSingleKvStoresingleKvStore;
//数据库名称
privatestaticfinalStringSTORE_NAME="MyStore";
//存入的数据key
privatestaticfinalStringKEY_COUNT="key_count";

@Override
publicvoidonStart(Intentintent){
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
requestPermission();
initDatabase();
initComponent();
}

/**
*请求分布式权限
*/
privatevoidrequestPermission(){
if(verifySelfPermission(DISTRIBUTED_DATASYNC)!=IBundleManager.PERMISSION_GRANTED){
if(canRequestPermission(DISTRIBUTED_DATASYNC)){
requestPermissionsFromUser(newString[]{DISTRIBUTED_DATASYNC},0);
}
}
}

/**
*初始化分布式数据库
*/
privatevoidinitDatabase(){
//创建分布式数据库管理器
kvManager=KvManagerFactory.getInstance().createKvManager(newKvManagerConfig(this));

//数据库配置
Optionsoptions=newOptions();
options.setCreateIfMissing(true)//设置数据库不存在时是否创建
.setEncrypt(false)//设置数据库是否加密
.setKvStoreType(KvStoreType.SINGLE_VERSION);//数据库类型
//创建分布式数据库
singleKvStore=kvManager.getKvStore(options,STORE_NAME);
//监听数据库数据改变
singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL,newKvStoreObserver(){
@Override
publicvoidonChange(ChangeNotificationchangeNotification){
ListinsertEntries=changeNotification.getInsertEntries();
ListupdateEntries=changeNotification.getUpdateEntries();

//第一次存入数据,获取insertEntries
if(insertEntries.size()>0){
for(Entryentry:insertEntries){
if(KEY_COUNT.equals(entry.getKey())){
//回调为非UI线程,需要在UI线程更新UI
getUITaskDispatcher().syncDispatch(()->{
intcount=entry.getValue().getInt();
text.setText("数据:"+count);
});
}
}
}elseif(updateEntries.size()>0){
for(Entryentry:updateEntries){
if(KEY_COUNT.equals(entry.getKey())){
//回调为非UI线程,需要在UI线程更新UI
getUITaskDispatcher().syncDispatch(()->{
intcount=entry.getValue().getInt();
text.setText("数据:"+count);
});
}
}
}
}
});

}

/**
*初始化组件
*/
privatevoidinitComponent(){
text=(Text)findComponentById(ResourceTable.Id_text);
Buttonbutton=(Button)findComponentById(ResourceTable.Id_button);

//点击事件
button.setClickedListener(component->{
try{
intcount=singleKvStore.getInt(KEY_COUNT);
singleKvStore.putInt(KEY_COUNT,count+1);
}catch(KvStoreExceptione){
e.printStackTrace();
//没有找到,首次进入
if(e.getKvStoreErrorCode()==KvStoreErrorCode.KEY_NOT_FOUND){
intcount=0;
singleKvStore.putInt(KEY_COUNT,count+1);
}
}
});
}
}
注释比较详细,主要注意 2 个点:
  • 获取数据时加入 try catch 块,处理 key 未找到的情况。

  • 数据库数据改变监听回调是非 UI 线程,如果更新 UI 必须切换到 UI 线程。

以上简单案例就是让你快速掌握分布式数据服务:多个设备相同的应用之间使用同一个数据库。 项目地址(需要登录才能看到演示图):
https://gitee.com/liangdidi/DistributedChatDemo.git
作者:梁青松
编辑:jq
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    7006

    浏览量

    88955
  • 数据库
    +关注

    关注

    7

    文章

    3795

    浏览量

    64366
  • ui
    ui
    +关注

    关注

    0

    文章

    204

    浏览量

    21369
  • 代码
    +关注

    关注

    30

    文章

    4780

    浏览量

    68539

原文标题:一款鸿蒙分布式聊天室应用!

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony威廉希尔官方网站 社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    鸿蒙ArkTS声明开发:跨平台支持列表【分布式迁移标识】 通用属性

    组件的分布式迁移标识,指明了该组件在分布式迁移场景下可以将特定状态恢复到对端设备。
    的头像 发表于 06-07 21:15 395次阅读

    鸿蒙开发接口数据管理:【@ohos.data.distributedDataObject (分布式数据对象)】

    本模块提供管理基本数据对象的相关能力,包括创建、查询、删除、修改、订阅等;同时支持相同应用多设备间的分布式数据对象协同能力。
    的头像 发表于 06-07 17:51 1484次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>开发</b>接口<b class='flag-5'>数据</b>管理:【@ohos.data.distributedDataObject (<b class='flag-5'>分布式</b><b class='flag-5'>数据</b>对象)】

    鸿蒙开发接口数据管理:【@ohos.data.distributedData (分布式数据管理)】

    分布式数据管理为应用程序提供不同设备间数据库的分布式协同能力。通过调用分布式数据各个接口,应用程
    的头像 发表于 06-07 09:30 977次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>开发</b>接口<b class='flag-5'>数据</b>管理:【@ohos.data.distributedData (<b class='flag-5'>分布式</b><b class='flag-5'>数据</b>管理)】

    HarmonyOS开发实例:【分布式数据服务

    分布式数据服务(Distributed Data Service,DDS)为应用程序提供不同设备间数据分布式的能力。
    的头像 发表于 04-18 10:18 714次阅读
    HarmonyOS<b class='flag-5'>开发</b>实例:【<b class='flag-5'>分布式</b><b class='flag-5'>数据服务</b>】

    OpenHarmony南向开发案例:【分布式画板】

    使用OpenHarmony3.1-Release开发的应用。通过OpenHarmony的分布式威廉希尔官方网站 ,使多人能够一起画画。
    的头像 发表于 04-12 14:40 1036次阅读
    OpenHarmony南向<b class='flag-5'>开发</b>案例:【<b class='flag-5'>分布式</b>画板】

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

    eTS中分布式数据管理的使用,包括KVManager对象实例的创建和KVStore数据流转的使用。
    的头像 发表于 04-11 09:57 931次阅读
    HarmonyOS<b class='flag-5'>开发</b>实例:【<b class='flag-5'>分布式</b><b class='flag-5'>数据</b>管理】

    鸿蒙HarmonyOS开发实例:【分布式关系型数据库】

    使用[@ohos.data.relationalStore]接口和[@ohos.distributedDeviceManager] 接口展示了在eTS中分布式关系型数据库的使用,在增、删、改、查的基本操作外,还包括分布式数据库的
    的头像 发表于 04-11 09:52 921次阅读
    <b class='flag-5'>鸿蒙</b>HarmonyOS<b class='flag-5'>开发</b>实例:【<b class='flag-5'>分布式</b>关系型<b class='flag-5'>数据</b>库】

    鸿蒙HarmonyOS开发实战:【分布式音乐播放】

    本示例使用fileIo获取指定音频文件,并通过AudioPlayer完成了音乐的播放完成了基本的音乐播放、暂停、上一曲、下一曲功能;并使用DeviceManager完成了分布式设备列表的显示和分布式能力完成了音乐播放状态的跨设备分享。
    的头像 发表于 04-10 17:51 868次阅读
    <b class='flag-5'>鸿蒙</b>HarmonyOS<b class='flag-5'>开发</b>实战:【<b class='flag-5'>分布式</b>音乐播放】

    UEFIRC:运行于UEFI环境下的IRC聊天室

    据悉,开源开发者Phillip Tennen展示了基于UEFI的沉浸IRC网络聊天室:UREFIRC原型设计。该设计无需进入操作系统,仅在UEFI环境内运行。
    的头像 发表于 04-08 16:16 584次阅读

    分布式存储与计算:大数据时代的解决方案

    分布式存储和计算威廉希尔官方网站 应运而生,并迅速成为处理大数据的首选方案。本文将深入探讨分布式存储和计算的概念、优势及其在各个领域的应用情况。 1.分布式存储和计算的概念与优势
    的头像 发表于 03-07 14:42 758次阅读

    鸿蒙实战项目开发:【短信服务

    数据管理 电话服务 分布式应用开发 通知与窗口管理 多媒体威廉希尔官方网站 安全技能 任务管理 WebGL 国际化开发 应用测试 DFX面向未来设计
    发表于 03-03 21:29

    鸿蒙OS 分布式任务调度

    形式、数据结构、服务描述语言,屏蔽硬件差异;支持远程启动、远程调用、业务无缝迁移等分布式任务。 分布式任务调度平台在底层实现 Ability(分布式
    的头像 发表于 01-29 16:50 489次阅读

    分布式节点服务器是什么?

    部署在不同的服务器上进行处理和存储,以实现负载均衡和容错处理。这种架构模式旨在提高系统的可扩展性、可靠性和性能表现,以满足大规模数据处理、复杂任务处理等需求。 分布式节点服务器的实现方
    的头像 发表于 01-12 15:04 740次阅读
    <b class='flag-5'>分布式</b>节点<b class='flag-5'>服务</b>器是什么?

    鸿蒙千帆起】《开心消消乐》完成鸿蒙原生应用开发,创新多端联动用户体验

    更优质的用户体验,基于强大的 AI 能力还可以实现精准识别、精确投放,为伙伴提供新流量,并共享全场景服务分发,助力生态共赢。数据显示,截至今年 8 月份,鸿蒙生态的设备数已超过 7 亿,鸿蒙
    发表于 01-03 10:22

    分布式IO工业自动化数据采集与分析的核心

    工业自动化生产的效率。在传统的工业自动化生产中,设备的控制和监测通常采用集中式控制方式,这种方式存在着设备连接复杂、数据传输速度慢、故障率高和扩展性差等问题。而分布式IO采用分布式控制方式,将设备按照
    发表于 12-28 14:47