首页 / 行业
基于鸿蒙分布式数据服务开发的聊天室应用
2021-12-03 10:35:00
之前给大家介绍过《HarmonyOS 分布式之仿抖音应用》,此次给大家介绍一下基于鸿蒙分布式数据服务开发的聊天室应用,模拟现实中的聊天室对话,可以与小伙伴们互动、分享自己的故事给小伙伴。
主要知识点
分布式数据服务:
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";//存入的列表数据keyprivatestaticfinalStringKEY_DATA="key_data";//存入的头像索引privatestaticfinalStringKEY_PIC_INDEX="key_pic_index";privateintpicIndex=0;@OverridepublicvoidonStart(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(){@OverridepublicvoidonChange(ChangeNotificationchangeNotification){ListinsertEntries=changeNotification.getInsertEntries();ListupdateEntries=changeNotification.getUpdateEntries();//第一次存入数据,获取insertEntriesif(insertEntries.size()>0){for(Entryentry:insertEntries){if(KEY_DATA.equals(entry.getKey())){//回调为非UI线程,需要在UI线程更新UIgetUITaskDispatcher().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线程更新UIgetUITaskDispatcher().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);}}}@OverrideprotectedvoidonStop(){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"}]
布局页面:<?xml version="1.0" encoding="utf-8"?><DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text"ohos:height="match_content"ohos:width="match_content"ohos:text="数据:0"ohos:text_size="15fp"/><Buttonohos: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";//存入的数据keyprivatestaticfinalStringKEY_COUNT="key_count";@OverridepublicvoidonStart(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(){@OverridepublicvoidonChange(ChangeNotificationchangeNotification){ListinsertEntries=changeNotification.getInsertEntries();ListupdateEntries=changeNotification.getUpdateEntries();//第一次存入数据,获取insertEntriesif(insertEntries.size()>0){for(Entryentry:insertEntries){if(KEY_COUNT.equals(entry.getKey())){//回调为非UI线程,需要在UI线程更新UIgetUITaskDispatcher().syncDispatch(()->{intcount=entry.getValue().getInt();text.setText("数据:"+count);});}}}elseif(updateEntries.size()>0){for(Entryentry:updateEntries){if(KEY_COUNT.equals(entry.getKey())){//回调为非UI线程,需要在UI线程更新UIgetUITaskDispatcher().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
最新内容
手机 |
相关内容
写flash芯片时为什么需要先擦除?
写flash芯片时为什么需要先擦除?,擦除,芯片,充电,初始状态,存储单元,数据,Flash芯片是一种非易失性存储器技术,用于存储数据并实现固半导体主控技术:驱动自动驾驶革命的
半导体主控技术:驱动自动驾驶革命的引擎,自动驾驶,交通,自动驾驶系统,数据,车辆,自动,随着科技的不断进步,自动驾驶技术已经成为现实电容式触摸按键屏中应用的高性能触
电容式触摸按键屏中应用的高性能触摸芯片,芯片,位置,触摸屏,能力,响应,用户,电容式触摸按键屏(Capacitive Touch Key Screen)是一种常苹果即将推出Mac系列新品,或搭载3nm
苹果即将推出Mac系列新品,或搭载3nm M3芯片,芯片,搭载,推出,全新,市场,研发,近日,有关苹果即将推出新一代Mac系列产品的消息引起了广STC15W芯片A/D、D/A转换的简单使用
STC15W芯片A/D、D/A转换的简单使用,简单使用,转换,芯片,模拟,输入,输出,STC15W系列芯片是一种高性能的单片机芯片,具有丰富的外设资Arbe 4D成像雷达以高分辨率雷达技
Arbe 4D成像雷达以高分辨率雷达技术和先进处理技术消除“幽灵刹车”问题,刹车,成像,分辨率,系统,目标,数据,Arbe 4D成像雷达是一种清华大学研发光电融合芯片,算力超商
清华大学研发光电融合芯片,算力超商用芯片三千余倍,芯片,研发,商用,测试,计算,科学研究,近日,清华大学发布了一项重要科研成果,他们成苹果发布M3系列新款MacBook Pro/iM
苹果发布M3系列新款MacBook Pro/iMac:业界首批PC 3nm芯片,新款,芯片,业界,核心,用户,性能,近日,苹果公司发布了M3系列新款MacBook Pro