HarmonyOS 分散チャットルームアプリケーション

HarmonyOS 分散チャットルームアプリケーション

[[434771]]

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ

https://harmonyos..com

導入

以前、[#星光计划1.0# HarmonyOS 分散型 TikTok 風アプリケーション] を紹介しました。今回は、HarmonyOS 分散データ サービスをベースに開発されたチャット ルーム アプリケーションを紹介します。実際のチャットルームでの会話をシミュレートし、友達と交流したり、ストーリーを共有したりすることができます。

効果のデモンストレーション


プロジェクトクラスの説明


主な知識ポイント

分散データサービス

公式紹介: 分散データ サービスは、主にユーザー デバイス内のアプリケーションのデータ コンテンツの分散同期を実現します。デバイス 1 上のアプリケーション A が分散データベース内のデータを追加、削除、または変更すると、デバイス 2 上のアプリケーション A もデータベースの変更を取得できます。要約すると、複数のデバイスが 1 つのデータベースを共有します。

ホームページコード

特に複雑なロジックはなく、分散データサービスの利用が中心で、要所にコメントが入っています。

  1. com.ldd.myapp.bean.ChatDataBean をインポートします。
  2. com.ldd.myapp.provider.ChatProvider をインポートします。
  3. com.ldd.myapp.util.Tools をインポートします。
  4. ohos.aafwk.ability.AbilitySlice をインポートします。
  5. ohos.aafwk.content.Intent をインポートします。
  6. ohos.agp.components.Button をインポートします。
  7. ohos.agp.components.ListContainer をインポートします。
  8. ohos.agp.components.TextField をインポートします。
  9. ohos.app.Context をインポートします。
  10. ohos.bundle.IBundleManager をインポートします。
  11. ohos.data.distributed.common.* をインポートします。
  12. ohos.data.distributed.user .SingleKvStoreをインポートします
  13. ohos.utils.zson.ZSONArray をインポートします。
  14. ohos.utils.zson.ZSONObject をインポートします。
  15.  
  16. java.util.ArrayList をインポートします。
  17. java.util.List をインポートします。
  18.  
  19. 静的ohos.security.SystemPermission.DISTRIBUTED_DATASYNC をインポートします。
  20.  
  21. /**
  22. * ホームページ
  23. */
  24. パブリッククラス MainAbilitySlice は AbilitySlice を拡張します {
  25. プライベートコンテキストmContext;
  26. // チャットリスト
  27. プライベート ListContainer lcList;
  28. //チャットデータ
  29. プライベート最終リスト<ChatDataBean> listData = new ArrayList<>();
  30. //チャットデータアダプタ
  31. プライベート ChatProvider チャットプロバイダー;
  32. // 入力ボックス
  33. プライベート TextField tfContent;
  34. //送信ボタン
  35. プライベートボタン btnSend;
  36.  
  37. // 分散データベースマネージャー
  38. プライベート KvManager kvManager;
  39. // 分散データベース
  40. プライベート SingleKvStore シングルKvストア;
  41. // データベース名
  42. プライベート静的最終文字列 STORE_NAME = "ChatStore" ;
  43. // 保存されたリストデータキー 
  44. プライベート静的最終文字列 KEY_DATA = "key_data" ;
  45. // 保存されたアバターのインデックス
  46. プライベート静的最終文字列 KEY_PIC_INDEX = "key_pic_index" ;
  47. プライベートint picIndex = 0;
  48.  
  49. @オーバーライド
  50. パブリックvoid onStart(インテント インテント) {
  51. super.onStart(インテント);
  52. UIContent をスーパーに設定します。
  53. mContext = これ;
  54. リクエストパーミッション();
  55. コンポーネントを初期化します。
  56. データベースを初期化します。
  57. }
  58.  
  59. /**
  60. * 分散権限を要求する
  61. */
  62. プライベートvoid requestPermission() {
  63. if (verifySelfPermission(DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) {
  64. (DISTRIBUTED_DATASYNCの許可をリクエストできる場合){
  65. requestPermissionsFromUser(新しい文字列[]{DISTRIBUTED_DATASYNC}, 0);
  66. }
  67. }
  68. }
  69.  
  70. /**
  71. * コンポーネントを初期化する
  72. */
  73. プライベートvoid initComponent() {
  74. lcList = (ListContainer) リソーステーブルId_lc_list でコンポーネントIDを検索します。
  75. tfContent = (テキストフィールド) findComponentById(ResourceTable.Id_tf_content);
  76. tfContent.setAdjustInputPanel( true );
  77. btnSend = (ボタン) findComponentById(ResourceTable.Id_btn_send);
  78. btnSend.setEnabled( false );
  79.  
  80. // アダプタを初期化する
  81. チャットプロバイダー = 新しいチャットプロバイダー (mContext、リストデータ);
  82. lcList.setItemProvider(チャットプロバイダー);
  83.  
  84. // 入力ボックスの内容変更の監視
  85. tfContent.addTextObserver((テキスト、開始、前、カウント) -> {
  86. btnSend.setEnabled(text.length() != 0);
  87. });
  88. // 送信ボタンをクリック
  89. btnSend.setClickedListener(コンポーネント -> {
  90. 文字列コンテンツ = tfContent.getText().trim();
  91. listData.add (新しい ChatDataBean(Tools.getDeviceId(mContext),picIndex,content));
  92. // データベースに保存
  93. 単一のKvStore.putString(KEY_DATA、ZSONObject.toZSONString(listData));
  94.  
  95. // 入力ボックスをクリアする
  96. tfContent.setText( "" );
  97. });
  98. }
  99.  
  100. /**
  101. * 分散データベースを初期化する
  102. */
  103. プライベートvoid initDatabase() {
  104. // 分散データベースマネージャーを作成する
  105. kvManager = KvManagerFactory.getInstance().createKvManager(新しい KvManagerConfig(this));
  106.  
  107. // データベース構成
  108. オプション options = new Options();
  109. options.setCreateIfMissing( true ) // データベースが存在しない場合に作成するかどうかを設定します
  110. .setEncrypt( false ) // データベースが暗号化されているかどうかを設定します
  111. .setKvStoreType(KvStoreType.SINGLE_VERSION); //データベースタイプ
  112. // 分散データベースを作成する
  113. 単一のKvStore = kvManager.getKvStore(オプション、STORE_NAME);
  114. //データベースデータの変更を監視する
  115. 単一のKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL、新しいKvStoreObserver() {
  116. @オーバーライド
  117. パブリックvoid onChange(ChangeNotification changeNotification) {
  118. リスト<Entry> insertEntries = changeNotification.getInsertEntries();
  119. リスト<Entry> updateEntries = changeNotification.getUpdateEntries();
  120.  
  121. // 初めてデータを保存するときは、insertEntries を取得します
  122. (挿入エントリのサイズ( )>0)の場合{
  123. for (エントリ entry : insertEntries) {
  124. KEY_DATAがentry.getKey()と等しい場合{
  125. // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
  126. getUITaskDispatcher().syncDispatch(() -> {
  127. リストデータをクリアします。
  128. listData.addAll(ZSONArray.stringToClassList(entry.getValue().getString(),ChatDataBean.class));
  129. チャットプロバイダーに通知データが変更されました();
  130. lcList.scrollTo(リストデータ.size () - 1);
  131. });
  132. }
  133. }
  134. }そうでない場合( updateEntries.size ()>0){
  135. for (エントリ entry : updateEntries) {
  136. KEY_DATAがentry.getKey()と等しい場合{
  137. // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
  138. getUITaskDispatcher().syncDispatch(() -> {
  139. リストデータをクリアします。
  140. listData.addAll(ZSONArray.stringToClassList(entry.getValue().getString(),ChatDataBean.class));
  141. チャットプロバイダーに通知データが変更されました();
  142. lcList.scrollTo(リストデータ.size () - 1);
  143. });
  144. }
  145. }
  146. }
  147. }
  148. });
  149.  
  150. 試す {
  151. picIndex = singleKvStore.getInt(KEY_PIC_INDEX);
  152. singleKvStore.putInt(KEY_PIC_INDEX, picIndex + 1);
  153. } キャッチ (KvStoreException e) {
  154. e.printStackTrace();
  155. // 見つかりません、最初のエントリ
  156. (e.getKvStoreErrorCode() == KvStoreErrorCode.KEY_NOT_FOUND) の場合 {
  157. picインデックス = 0;
  158. singleKvStore.putInt(KEY_PIC_INDEX, picIndex + 1);
  159. }
  160. }
  161. }
  162.  
  163. @オーバーライド
  164. 保護されたvoid onStop() {
  165. スーパーのonStop();
  166. kvManager.closeKvStore(単一のKvStore);
  167. }
  168. }

シンプルなケース

1. config.json の設定

  1. 「必要な権限」 : [
  2. {
  3. 「理由」 「マルチデバイスコラボレーション」
  4. 「名前」 : 「ohos.permission.DISTRIBUTED_DATASYNC」
  5. 「使用シーン」 : {
  6. "能力" : [
  7. 「メインアビリティ」  
  8. ]、
  9. 「いつ」 「常に」  
  10. }
  11. },
  12. {
  13. 「名前」 : 「ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE」  
  14. },
  15. {
  16. 「名前」 : 「ohos.permission.GET_DISTRIBUTED_DEVICE_INFO」  
  17. },
  18. {
  19. 「名前」 : 「ohos.permission.GET_BUNDLE_INFO」  
  20. }
  21. ]

2. レイアウトページ

  1. <?xml バージョン = "1.0"エンコーディング = "utf-8" ?>
  2. <方向レイアウト
  3. xmlns:ohos= "http://schemas.huawei.com/res/ohos"  
  4. ohos:height= "match_parent"  
  5. ohos:width= "match_parent"  
  6. ohos:alignment= "中央"  
  7. ohos:orientation= "垂直" >
  8.  
  9. <テキスト
  10. ohos:id= "$+id:テキスト"  
  11. ohos:height= "match_content"  
  12. ohos:width= "match_content"  
  13. ohos:text= "データ:0"  
  14. ohos:text_size= "15fp" />
  15.  
  16. <ボタン
  17. ohos:margin= "20vp"  
  18. ohos:id= "$+id:ボタン"  
  19. ohos:height= "match_content"  
  20. ohos:width= "match_parent"  
  21. ohos:background_element= "$graphic:button_bg"  
  22. ohos:padding= "10vp"  
  23. ohos:text= "+1 をクリック"  
  24. ohos:text_color= "白"  
  25. ohos:text_size= "15fp" />
  26.  
  27. </方向レイアウト>

3. MainAbilitySliceコード

  1. ohos.aafwk.ability.AbilitySlice をインポートします。
  2. ohos.aafwk.content.Intent をインポートします。
  3. ohos.agp.components.Button をインポートします。
  4. ohos.agp.components.ListContainer をインポートします。
  5. ohos.agp.components.Text をインポートします。
  6. ohos.agp.components.TextField をインポートします。
  7. ohos.bundle.IBundleManager をインポートします。
  8. ohos.data.distributed.common.* をインポートします。
  9. ohos.data.distributed.user .SingleKvStoreをインポートします
  10. ohos.utils.zson.ZSONArray をインポートします。
  11.  
  12. java.util.List をインポートします。
  13.  
  14. 静的ohos.security.SystemPermission.DISTRIBUTED_DATASYNC をインポートします。
  15.  
  16. パブリッククラス MainAbilitySlice は AbilitySlice を拡張します {
  17. // データを表示
  18. プライベートテキストテキスト;
  19. // 分散データベースマネージャー
  20. プライベート KvManager kvManager;
  21. // 分散データベース
  22. プライベート SingleKvStore シングルKvストア;
  23. // データベース名
  24. プライベート静的最終文字列 STORE_NAME = "MyStore" ;
  25. // 保存するデータキー 
  26. プライベート静的最終文字列 KEY_COUNT = "key_count" ;
  27.  
  28. @オーバーライド
  29. パブリックvoid onStart(インテント インテント) {
  30. super.onStart(インテント);
  31. UIContent をスーパーに設定します。
  32. リクエストパーミッション();
  33. データベースを初期化します。
  34. コンポーネントを初期化します。
  35. }
  36.  
  37. /**
  38. * 分散権限を要求する
  39. */
  40. プライベートvoid requestPermission() {
  41. if (verifySelfPermission(DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) {
  42. (DISTRIBUTED_DATASYNCの許可をリクエストできる場合){
  43. requestPermissionsFromUser(新しい文字列[]{DISTRIBUTED_DATASYNC}, 0);
  44. }
  45. }
  46. }
  47.  
  48. /**
  49. * 分散データベースを初期化する
  50. */
  51. プライベートvoid initDatabase() {
  52. // 分散データベースマネージャーを作成する
  53. kvManager = KvManagerFactory.getInstance().createKvManager(新しい KvManagerConfig(this));
  54.  
  55. // データベース構成
  56. オプション options = new Options();
  57. options.setCreateIfMissing( true ) // データベースが存在しない場合に作成するかどうかを設定します
  58. .setEncrypt( false ) // データベースが暗号化されているかどうかを設定します
  59. .setKvStoreType(KvStoreType.SINGLE_VERSION); //データベースタイプ
  60. // 分散データベースを作成する
  61. 単一の KvStore = kvManager.getKvStore(オプション、STORE_NAME);
  62. //データベースデータの変更を監視する
  63. 単一のKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL、新しいKvStoreObserver() {
  64. @オーバーライド
  65. パブリックvoid onChange(ChangeNotification changeNotification) {
  66. リスト<Entry> insertEntries = changeNotification.getInsertEntries();
  67. リスト<エントリ> updateEntries = changeNotification.getUpdateEntries();
  68.  
  69. // 初めてデータを保存するときは、insertEntries を取得します
  70. ( insertEntries.size () > 0)の場合{
  71. for (エントリ entry : insertEntries) {
  72. KEY_COUNTがentry.getKey()と等しい場合{
  73. // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
  74. getUITaskDispatcher().syncDispatch(() -> {
  75. 整数 カウント= entry.getValue().getInt();
  76. text.setText( "データ: " + count );
  77. });
  78. }
  79. }
  80. }そうでない場合( updateEntries.size () > 0) {
  81. for (エントリ entry : updateEntries) {
  82. KEY_COUNTがentry.getKey()と等しい場合{
  83. // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
  84. getUITaskDispatcher().syncDispatch(() -> {
  85. 整数 カウント= entry.getValue().getInt();
  86. text.setText( "データ: " + count );
  87. });
  88. }
  89. }
  90. }
  91. }
  92. });
  93.  
  94. }
  95.  
  96. /**
  97. * コンポーネントを初期化する
  98. */
  99. プライベートvoid initComponent() {
  100. テキスト = (テキスト) findComponentById(ResourceTable.Id_text);
  101. ボタン button = (Button) findComponentById(ResourceTable.Id_button);
  102.  
  103. // クリックイベント
  104. button.setClickedListener(コンポーネント -> {
  105. 試す {
  106. 整数 カウント= singleKvStore.getInt(KEY_COUNT);
  107. 単一のKvStore.putInt(KEY_COUNT、カウント+1);
  108. } キャッチ (KvStoreException e) {
  109. e.printStackTrace();
  110. // 見つかりません、最初のエントリ
  111. (e.getKvStoreErrorCode() == KvStoreErrorCode.KEY_NOT_FOUND) の場合 {
  112. 整数 カウント= 0;
  113. 単一のKvStore.putInt(KEY_COUNT、カウント+1);
  114. }
  115. }
  116. });
  117. }
  118. }

コメントは非常に詳細で、主に次の 2 つの点に注目してください。

  1. キーが見つからない状況に対処するために、データを取得するときにtry catchブロックを追加します。
  2. データベース データ変更監視コールバックは非 UI スレッドです。 UI を更新する場合は、UI スレッドに切り替える必要があります。

上記の簡単なケースは、複数のデバイス上の同じアプリケーション間で同じデータベースを使用する分散データ サービスをすぐに習得するのに役立ちます。

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ

https://harmonyos..com

<<:  JavaAgent を使用して JVM を騙す

>>:  マルチクラウド戦略を構築するための考慮事項

推薦する

Baiduオリジナル記事と転載検出アルゴリズム

インターネットの急速な発展に伴い、ネットワーク上には重複したリソース ファイルが大量に存在します。た...

メンガー: 大規模分散強化学習アーキテクチャ

過去 10 年間で、強化学習 (RL) は機械学習における最も人気のある研究分野の 1 つになりまし...

新しいウェブサイトの SEO を素早く「始める」ための 5 つのコツをマスターする

新しいウェブサイトを最適化することは、初心者の SEO 担当者にとって決して簡単な作業ではありません...

重慶フォーラムの運営経験:コンテンツが王様、口コミによる宣伝が女王

今夜、私はベッドの中で寝返りを打ちながら、インターネットビジネスを始めたときの経験を思い返しました。...

2022年のクラウドコンピューティング開発のトレンド

感染症の流行から国際的なサプライチェーンの問題まで、近年、世界のビジネス環境は大きく変化しており、私...

開始: Hostgator 50% オフ、com 登録 $2.95

Hostgator から、22 日の深夜から中部標準時の午後 11 時 59 分までプロモーションが...

ロボットファイルを使用してウェブサイトの構成を最適化する手順

個人の能力が向上するにつれ、いくつかの新しいプロジェクトの運用を担当するようになりました。これらのプ...

クラウドネイティブアプリケーションのセキュリティ組織アーキテクチャの簡単な分析

デジタル変革は無視できない力です。あらゆる業種において、企業はテクノロジー企業になることを目指してお...

Qianyun Technology SmartCMP v3.5が正式にリリースされました

SmartCMP ハイブリッド クラウド自動化管理プラットフォーム 3.5 は、アプリケーション配信...

K8s の交換が必要です!

著者 |趙雲現在、Kubernetes はマイクロサービスのデプロイメント問題を解決し、すでにコンテ...

「オンデマンドカスタマイズ」と柔軟な展開で、JD Cloudの「クラウドサービス」がファンを獲得

クラウドコンピューティング、5G、ビッグデータ、人工知能などの新興技術の急速な発展に伴い、データセン...

Huayun Data のハイパーコンバージェンスにより、Guangzhou Sematic は新しい「クラウド」オフィス モデルを構築

時間が足りないと感じ始めたのはいつですか? 8時間480分28800秒、これは、すべてのオフィスワー...

ウェブサイトのユーザー利用率を効果的に高める方法

最近、インターネットの高速化が話題になっています。もちろん、これは中国でウェブサイトを構築する人が増...

VMware CEOがクラウドコンピューティング開発計画を議論するため初めて中国を訪問

2010 年 3 月 5 日の午後、VMware 社長兼 CEO のポール マリッツは中国訪問中に北...

モモライブ、もう人気ないの?

Momo は、iPhone、Android、Windows Phone をベースに Momo Tec...