• 1
  • 2
  • 3
  • 4

首页 / 行业

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

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

数据服务数据库聊天室

  • 1
  • 2
  • 3
  • 4

最新内容

手机

相关内容

  • 1
  • 2
  • 3

猜你喜欢