之前給大家介紹過《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";
//存入的列表數據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
責任編輯:haq
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
數據
+關注
關注
8文章
7335瀏覽量
94773 -
鴻蒙系統
+關注
關注
183文章
2642瀏覽量
69850 -
HarmonyOS
+關注
關注
80文章
2153瀏覽量
36053
原文標題:一款鴻蒙分布式聊天室應用!
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
熱點推薦
TiDB分布式數據庫運維實踐
TiDB 是 PingCAP 開發的開源分布式關系型數據庫,兼容 MySQL 5.7 協議,底層存儲基于 TiKV(分布式 KV 存儲)和 RocksDB。它解決的核心問題是:當單機
SC-3568HA:解鎖鴻蒙全權限API與分布式能力的工業控制平臺
傳統嵌入式開發面臨硬件碎片化、高權限功能缺失、分布式協同復雜及自動化測試不足等痛點。SC-3568HA開發板基于鴻蒙系統,通過統一內核抽象層和硬件驅動框架解決兼容問題,開放全量系統AP
如何解決分布式光伏計量難題?
%。同時,可提升發電效率、降低發電成本的新型技術逐步落地,推動光伏系統向更高效、更緊湊的方向發展,進而對電表在精度、數據更新速度及適配性方面也提出了更高要求。 分布式光伏遇計量難題 分布式光伏常用 “自己發的電自己用,用不完的賣
【節能學院】Acrel-1000DP分布式光伏監控系統在奉賢平高食品 4.4MW 分布式光伏中應用
分布式光伏本地和遠程通信方案,并研究分布式光伏采集模型的構建、多源數據融合估計、面向分布式光伏的有功、無功功率優化控制等關鍵技術,實現了對小容量工商業
分布式光伏發電監測系統技術方案
分布式光伏發電監測系統技術方案 柏峰【BF-GFQX】一、系統目標 :分布式光伏發電監測系統旨在通過智能化的監測手段,實現對分布式光伏電站的全方位、高精度、實時化管理。該系統能
開鴻開發板深度體驗:從開源鴻蒙開發到AI場景實踐
的KaihongBoard-3588S-SBC和KaihongBoard-3576-SBC被評為“2025OpenHarmony明星開發板”,可實現設備快速開源鴻蒙化升級、分布式互聯協同、彈性部署等能力。
鴻蒙5開發寶藏案例分享---一多開發實例(音樂)
各位開發者小伙伴們好呀!今天咱們來點硬核干貨!最近在鴻蒙文檔中心挖到一座“金礦”——官方竟然暗藏了100+實戰案例,從分布式架構到交互動效優化應有盡有!這些案例不僅藏著華為工程師的私房技巧,還直接
vsan數據恢復—vsan分布式服務器節點上raid數據恢復案例
4臺服務器基于vsan分布式架構的組建一個集群。每臺節點服務器上有2組由6塊硬盤組建的raid磁盤陣列,上層存放虛擬機文件。
某一個服務器節點上有一塊硬盤離線,vsan的
鴻蒙5開發寶藏案例分享---應用接續提升內容發布體驗
: [distributedAsset] // 關鍵!這里放的是分布式文件引用
});
// 激活數據同步(相當于啟動數據快遞服務)
this.distributedObject.s
發表于 06-03 18:25
鴻蒙5開發寶藏案例分享---一多開發實例(游戲)
十年前藏的現金一樣驚喜!)這些藏在文檔深處的\"武功秘籍\",能幫我們輕松實現分布式游戲、跨端協同這些聽起來很酷的功能。快上車,帶你解鎖鴻蒙開發的正確姿勢!
一、分布式游戲手柄
發表于 06-03 18:22
曙光存儲領跑中國分布式存儲市場
近日,賽迪顧問發布《中國分布式存儲市場研究報告(2025)》,指出2024 年中國分布式存儲市場首次超過集中式存儲,規模達 198.2 億元,增速 43.7%。
分布式光伏電力問題層出不窮?安科瑞分布式光伏運維系統來“救場”
一、分布式光伏電力運維,痛點大揭秘? ? 分布式光伏作為實現綠色能源轉型的關鍵一環,近年來在我國得到了迅猛發展。國家能源局數據顯示,截至 2023 年底,中國分布式光伏電站累計并網容量
分布式存儲數據恢復—虛擬機上hbase和hive數據庫數據恢復案例
分布式存儲數據恢復環境:
16臺某品牌R730xd服務器節點,每臺服務器節點上有數臺虛擬機。
虛擬機上部署Hbase和Hive數據庫。
分布式光伏發運維系統實際應用案例分享
和可持續發展的重要推動力量。國家能源局于2025年1月發布了《分布式光伏發電開發建設管理辦法》,對分布式光伏的分類、上網模式、備案管理、電網接入等進行了詳細規定,未來分布式光伏將進一步
MCU分布式模塊化自動測量單元:數據傳輸與處理能力如何?
在現代工程監測中,MCU分布式模塊化自動測量單元(MCU)以其靈活的配置和強大的數據處理能力,成為了各類安全監測項目的理想選擇。本文將深入探討MCU的工作原理、數據傳輸方式以及其在實際應用中的優勢
基于鴻蒙分布式數據服務開發的聊天室應用
評論