之前给大家介绍过《harmonyos 分布式之仿抖音应用》,此次给大家介绍一下基于鸿蒙分布式数据服务开发的聊天室应用,模拟现实中的聊天室对话,可以与小伙伴们互动、分享自己的故事给小伙伴。
主要知识点
分布式数据服务:
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-mdds-guidelines-0000000000030122 官方介绍:分布式数据服务主要实现用户设备中应用程序的数据内容的分布式同步。
当设备 1 上的应用 a 在分布式数据库中增、删、改数据后,设备 2 上的应用 a 也可以获取到该数据库变化,总结一句话:多个设备共用一个数据库。
主页代码
没有特别复杂的逻辑,主要是分布式数据服务的使用,关键地方都有注释。import com.ldd.myapp.bean.chatdatabean;import com.ldd.myapp.provider.chatprovider;import com.ldd.myapp.util.tools;import ohos.aafwk.ability.abilityslice;import ohos.aafwk.content.intent;import ohos.agp.components.button;import ohos.agp.components.listcontainer;import ohos.agp.components.textfield;import ohos.app.context;import ohos.bundle.ibundlemanager;import ohos.data.distributed.common.*;import ohos.data.distributed.user.singlekvstore;import ohos.utils.zson.zsonarray;import ohos.utils.zson.zsonobject;import java.util.arraylist;import java.util.list;import static ohos.security.systempermission.distributed_datasync;/** * 主页 */public class mainabilityslice extends abilityslice { private context mcontext; // 聊天列表 private listcontainer lclist; // 聊天数据 private final list listdata = new arraylist(); // 聊天数据适配器 private chatprovider chatprovider; // 输入框 private textfield tfcontent; // 发送按钮 private button btnsend; // 分布式数据库管理器 private kvmanager kvmanager; // 分布式数据库 private singlekvstore singlekvstore; // 数据库名称 private static final string store_name = chatstore; // 存入的列表数据key private static final string key_data = key_data; // 存入的头像索引 private static final string key_pic_index = key_pic_index; private int picindex = 0; @override public void onstart(intent intent) { super.onstart(intent); super.setuicontent(resourcetable.layout_ability_main); mcontext = this; requestpermission(); initcomponent(); initdatabase(); } /** * 请求分布式权限 */ private void requestpermission() { if (verifyselfpermission(distributed_datasync) != ibundlemanager.permission_granted) { if (canrequestpermission(distributed_datasync)) { requestpermissionsfromuser(new string[]{distributed_datasync}, 0); } } } /** * 初始化组件 */ private void initcomponent() { 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 = new chatprovider(mcontext, listdata); lclist.setitemprovider(chatprovider); // 输入框内容变化监听 tfcontent.addtextobserver((text, start, before, count) -> { btnsend.setenabled(text.length() != 0); }); // 点击发送按钮 btnsend.setclickedlistener(component -> { string content = tfcontent.gettext().trim(); listdata.add(new chatdatabean(tools.getdeviceid(mcontext),picindex,content)); // 存入数据库中 singlekvstore.putstring(key_data, zsonobject.tozsonstring(listdata)); // 清空输入框 tfcontent.settext(); }); } /** * 初始化分布式数据库 */ private void initdatabase() { // 创建分布式数据库管理器 kvmanager = kvmanagerfactory.getinstance().createkvmanager(new kvmanagerconfig(this)); // 数据库配置 options options = new options(); options.setcreateifmissing(true) // 设置数据库不存在时是否创建 .setencrypt(false) // 设置数据库是否加密 .setkvstoretype(kvstoretype.single_version); //数据库类型 // 创建分布式数据库 singlekvstore = kvmanager.getkvstore(options, store_name); // 监听数据库数据改变 singlekvstore.subscribe(subscribetype.subscribe_type_all, new kvstoreobserver() { @override public void onchange(changenotification changenotification) { list insertentries = changenotification.getinsertentries(); list updateentries = changenotification.getupdateentries(); // 第一次存入数据,获取insertentries if(insertentries.size()>0){ for (entry entry : 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); }); } } }else if(updateentries.size()>0){ for (entry entry : 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 (kvstoreexception e) { e.printstacktrace(); // 没有找到,首次进入 if (e.getkvstoreerrorcode() == kvstoreerrorcode.key_not_found) { picindex = 0; singlekvstore.putint(key_pic_index, picindex + 1); } } } @override protected void onstop() { 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 } ]
布局页面: mainabilityslice 代码:import ohos.aafwk.ability.abilityslice;import ohos.aafwk.content.intent;import ohos.agp.components.button;import ohos.agp.components.listcontainer;import ohos.agp.components.text;import ohos.agp.components.textfield;import ohos.bundle.ibundlemanager;import ohos.data.distributed.common.*;import ohos.data.distributed.user.singlekvstore;import ohos.utils.zson.zsonarray;import java.util.list;import static ohos.security.systempermission.distributed_datasync;public class mainabilityslice extends abilityslice { // 显示数据 private text text; // 分布式数据库管理器 private kvmanager kvmanager; // 分布式数据库 private singlekvstore singlekvstore; // 数据库名称 private static final string store_name = mystore; // 存入的数据key private static final string key_count = key_count; @override public void onstart(intent intent) { super.onstart(intent); super.setuicontent(resourcetable.layout_ability_main); requestpermission(); initdatabase(); initcomponent(); } /** * 请求分布式权限 */ private void requestpermission() { if (verifyselfpermission(distributed_datasync) != ibundlemanager.permission_granted) { if (canrequestpermission(distributed_datasync)) { requestpermissionsfromuser(new string[]{distributed_datasync}, 0); } } } /** * 初始化分布式数据库 */ private void initdatabase() { // 创建分布式数据库管理器 kvmanager = kvmanagerfactory.getinstance().createkvmanager(new kvmanagerconfig(this)); // 数据库配置 options options = new options(); options.setcreateifmissing(true) // 设置数据库不存在时是否创建 .setencrypt(false) // 设置数据库是否加密 .setkvstoretype(kvstoretype.single_version); //数据库类型 // 创建分布式数据库 singlekvstore = kvmanager.getkvstore(options, store_name); // 监听数据库数据改变 singlekvstore.subscribe(subscribetype.subscribe_type_all, new kvstoreobserver() { @override public void onchange(changenotification changenotification) { list insertentries = changenotification.getinsertentries(); list updateentries = changenotification.getupdateentries(); // 第一次存入数据,获取insertentries if (insertentries.size() > 0) { for (entry entry : insertentries) { if (key_count.equals(entry.getkey())) { // 回调为非ui线程,需要在ui线程更新ui getuitaskdispatcher().syncdispatch(() -> { int count = entry.getvalue().getint(); text.settext(数据:+count); }); } } } else if (updateentries.size() > 0) { for (entry entry : updateentries) { if (key_count.equals(entry.getkey())) { // 回调为非ui线程,需要在ui线程更新ui getuitaskdispatcher().syncdispatch(() -> { int count = entry.getvalue().getint(); text.settext(数据:+count); }); } } } } }); } /** * 初始化组件 */ private void initcomponent() { text = (text) findcomponentbyid(resourcetable.id_text); button button = (button) findcomponentbyid(resourcetable.id_button); // 点击事件 button.setclickedlistener(component -> { try { int count = singlekvstore.getint(key_count); singlekvstore.putint(key_count, count + 1); } catch (kvstoreexception e) { e.printstacktrace(); // 没有找到,首次进入 if (e.getkvstoreerrorcode() == kvstoreerrorcode.key_not_found) { int count = 0; singlekvstore.putint(key_count, count + 1); } } }); }} 注释比较详细,主要注意 2 个点: 获取数据时加入 try catch 块,处理 key 未找到的情况。
数据库数据改变监听回调是非 ui 线程,如果更新 ui 必须切换到 ui 线程。
以上简单案例就是让你快速掌握分布式数据服务:多个设备相同的应用之间使用同一个数据库。 项目地址(需要登录才能看到演示图):https://gitee.com/liangdidi/distributedchatdemo.git 作者:梁青松
高通首款骁龙6系5G移动平台发布,带来5G普及重大利好
rs触发器的逻辑功能
远距离温度变送电路图
蓄电池电压电路图
多协议转换网关,快速连接工业设备到云平台
基于鸿蒙分布式数据服务开发的聊天室应用
LB5-66油浸式电流互感器
交换互联协议之概述详解
去中心化交易所可以分为哪些类型
简单的RS232C/TTL电平转换和串口取电,RS232C--TTL converter
索尼/OV摄像头芯片供货紧张将持续多久?
比特币和加密货币正在成为南美等地区的主要经济力量
详解HERO ChargeTM 的TWS充电方案
同步整流和异步整流介绍
光纤连接器的功能、结构与特性介绍
便携式叶绿素测定仪的实际使用效果怎么样
MiniLED是什么?有怎样的发展前景
如何给一颗芯片加上指纹?
国产首款四摄手机金立S10怎么样?
智能驾驶的“ChatGPT时刻”在哪?一套通用的智驾方案,足以迎来智驾的“ChatGPT时刻”