[[434771]] 詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ https://harmonyos..com 導入以前、[#星光计划1.0# HarmonyOS 分散型 TikTok 風アプリケーション] を紹介しました。今回は、HarmonyOS 分散データ サービスをベースに開発されたチャット ルーム アプリケーションを紹介します。実際のチャットルームでの会話をシミュレートし、友達と交流したり、ストーリーを共有したりすることができます。 効果のデモンストレーション
プロジェクトクラスの説明
主な知識ポイント分散データサービス 公式紹介: 分散データ サービスは、主にユーザー デバイス内のアプリケーションのデータ コンテンツの分散同期を実現します。デバイス 1 上のアプリケーション A が分散データベース内のデータを追加、削除、または変更すると、デバイス 2 上のアプリケーション A もデータベースの変更を取得できます。要約すると、複数のデバイスが 1 つのデータベースを共有します。 ホームページコード特に複雑なロジックはなく、分散データサービスの利用が中心で、要所にコメントが入っています。 - com.ldd.myapp.bean.ChatDataBean をインポートします。
- com.ldd.myapp.provider.ChatProvider をインポートします。
- com.ldd.myapp.util.Tools をインポートします。
- ohos.aafwk.ability.AbilitySlice をインポートします。
- ohos.aafwk.content.Intent をインポートします。
- ohos.agp.components.Button をインポートします。
- ohos.agp.components.ListContainer をインポートします。
- ohos.agp.components.TextField をインポートします。
- ohos.app.Context をインポートします。
- ohos.bundle.IBundleManager をインポートします。
- ohos.data.distributed.common.* をインポートします。
- ohos.data.distributed.user .SingleKvStoreをインポートします。
- ohos.utils.zson.ZSONArray をインポートします。
- ohos.utils.zson.ZSONObject をインポートします。
-
- java.util.ArrayList をインポートします。
- java.util.List をインポートします。
-
- 静的ohos.security.SystemPermission.DISTRIBUTED_DATASYNC をインポートします。
-
- /**
- * ホームページ
- */
- パブリッククラス MainAbilitySlice は AbilitySlice を拡張します {
- プライベートコンテキストmContext;
- // チャットリスト
- プライベート ListContainer lcList;
- //チャットデータ
- プライベート最終リスト<ChatDataBean> listData = new ArrayList<>();
- //チャットデータアダプタ
- プライベート ChatProvider チャットプロバイダー;
- // 入力ボックス
- プライベート TextField tfContent;
- //送信ボタン
- プライベートボタン btnSend;
-
- // 分散データベースマネージャー
- プライベート KvManager kvManager;
- // 分散データベース
- プライベート SingleKvStore シングルKvストア;
- // データベース名
- プライベート静的最終文字列 STORE_NAME = "ChatStore" ;
- // 保存されたリストデータキー
- プライベート静的最終文字列 KEY_DATA = "key_data" ;
- // 保存されたアバターのインデックス
- プライベート静的最終文字列 KEY_PIC_INDEX = "key_pic_index" ;
- プライベートint picIndex = 0;
-
- @オーバーライド
- パブリックvoid onStart(インテント インテント) {
- super.onStart(インテント);
- UIContent をスーパーに設定します。
- mContext = これ;
- リクエストパーミッション();
- コンポーネントを初期化します。
- データベースを初期化します。
- }
-
- /**
- * 分散権限を要求する
- */
- プライベートvoid requestPermission() {
- if (verifySelfPermission(DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) {
- (DISTRIBUTED_DATASYNCの許可をリクエストできる場合){
- requestPermissionsFromUser(新しい文字列[]{DISTRIBUTED_DATASYNC}, 0);
- }
- }
- }
-
- /**
- * コンポーネントを初期化する
- */
- プライベートvoid initComponent() {
- lcList = (ListContainer) リソーステーブルId_lc_list でコンポーネントIDを検索します。
- tfContent = (テキストフィールド) findComponentById(ResourceTable.Id_tf_content);
- tfContent.setAdjustInputPanel( true );
- btnSend = (ボタン) findComponentById(ResourceTable.Id_btn_send);
- btnSend.setEnabled( false );
-
- // アダプタを初期化する
- チャットプロバイダー = 新しいチャットプロバイダー (mContext、リストデータ);
- lcList.setItemProvider(チャットプロバイダー);
-
- // 入力ボックスの内容変更の監視
- tfContent.addTextObserver((テキスト、開始、前、カウント) -> {
- btnSend.setEnabled(text.length() != 0);
- });
- // 送信ボタンをクリック
- btnSend.setClickedListener(コンポーネント -> {
- 文字列コンテンツ = tfContent.getText().trim();
- listData.add (新しい ChatDataBean(Tools.getDeviceId(mContext),picIndex,content));
- // データベースに保存
- 単一のKvStore.putString(KEY_DATA、ZSONObject.toZSONString(listData));
-
- // 入力ボックスをクリアする
- tfContent.setText( "" );
- });
- }
-
- /**
- * 分散データベースを初期化する
- */
- プライベートvoid initDatabase() {
- // 分散データベースマネージャーを作成する
- kvManager = KvManagerFactory.getInstance().createKvManager(新しい KvManagerConfig(this));
-
- // データベース構成
- オプション options = new Options();
- options.setCreateIfMissing( true ) // データベースが存在しない場合に作成するかどうかを設定します
- .setEncrypt( false ) // データベースが暗号化されているかどうかを設定します
- .setKvStoreType(KvStoreType.SINGLE_VERSION); //データベースタイプ
- // 分散データベースを作成する
- 単一のKvStore = kvManager.getKvStore(オプション、STORE_NAME);
- //データベースデータの変更を監視する
- 単一のKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL、新しいKvStoreObserver() {
- @オーバーライド
- パブリックvoid onChange(ChangeNotification changeNotification) {
- リスト<Entry> insertEntries = changeNotification.getInsertEntries();
- リスト<Entry> updateEntries = changeNotification.getUpdateEntries();
-
- // 初めてデータを保存するときは、insertEntries を取得します
- (挿入エントリのサイズ( )>0)の場合{
- for (エントリ entry : insertEntries) {
- KEY_DATAがentry.getKey()と等しい場合{
- // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
- getUITaskDispatcher().syncDispatch(() -> {
- リストデータをクリアします。
- listData.addAll(ZSONArray.stringToClassList(entry.getValue().getString(),ChatDataBean.class));
- チャットプロバイダーに通知データが変更されました();
- lcList.scrollTo(リストデータ.size () - 1);
- });
- }
- }
- }そうでない場合( updateEntries.size ()>0){
- for (エントリ entry : updateEntries) {
- KEY_DATAがentry.getKey()と等しい場合{
- // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
- getUITaskDispatcher().syncDispatch(() -> {
- リストデータをクリアします。
- listData.addAll(ZSONArray.stringToClassList(entry.getValue().getString(),ChatDataBean.class));
- チャットプロバイダーに通知データが変更されました();
- lcList.scrollTo(リストデータ.size () - 1);
- });
- }
- }
- }
- }
- });
-
- 試す {
- picIndex = singleKvStore.getInt(KEY_PIC_INDEX);
- singleKvStore.putInt(KEY_PIC_INDEX, picIndex + 1);
- } キャッチ (KvStoreException e) {
- e.printStackTrace();
- // 見つかりません、最初のエントリ
- (e.getKvStoreErrorCode() == KvStoreErrorCode.KEY_NOT_FOUND) の場合 {
- picインデックス = 0;
- singleKvStore.putInt(KEY_PIC_INDEX, picIndex + 1);
- }
- }
- }
-
- @オーバーライド
- 保護されたvoid onStop() {
- スーパーのonStop();
- kvManager.closeKvStore(単一のKvStore);
- }
- }
シンプルなケース1. config.json の設定- 「必要な権限」 : [
- {
- 「理由」 : 「マルチデバイスコラボレーション」 、
- 「名前」 : 「ohos.permission.DISTRIBUTED_DATASYNC」 、
- 「使用シーン」 : {
- "能力" : [
- 「メインアビリティ」
- ]、
- 「いつ」 : 「常に」
- }
- },
- {
- 「名前」 : 「ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE」
- },
- {
- 「名前」 : 「ohos.permission.GET_DISTRIBUTED_DEVICE_INFO」
- },
- {
- 「名前」 : 「ohos.permission.GET_BUNDLE_INFO」
- }
- ]
2. レイアウトページ- <?xml バージョン = "1.0"エンコーディング = "utf-8" ?>
- <方向レイアウト
- xmlns:ohos= "http://schemas.huawei.com/res/ohos"
- ohos:height= "match_parent"
- ohos:width= "match_parent"
- ohos:alignment= "中央"
- ohos:orientation= "垂直" >
-
- <テキスト
- ohos:id= "$+id:テキスト"
- ohos:height= "match_content"
- ohos:width= "match_content"
- ohos:text= "データ:0"
- ohos:text_size= "15fp" />
-
- <ボタン
- ohos:margin= "20vp"
- ohos:id= "$+id:ボタン"
- ohos:height= "match_content"
- ohos:width= "match_parent"
- ohos:background_element= "$graphic:button_bg"
- ohos:padding= "10vp"
- ohos:text= "+1 をクリック"
- ohos:text_color= "白"
- ohos:text_size= "15fp" />
-
- </方向レイアウト>
3. MainAbilitySliceコード- ohos.aafwk.ability.AbilitySlice をインポートします。
- ohos.aafwk.content.Intent をインポートします。
- ohos.agp.components.Button をインポートします。
- ohos.agp.components.ListContainer をインポートします。
- ohos.agp.components.Text をインポートします。
- ohos.agp.components.TextField をインポートします。
- ohos.bundle.IBundleManager をインポートします。
- ohos.data.distributed.common.* をインポートします。
- ohos.data.distributed.user .SingleKvStoreをインポートします。
- ohos.utils.zson.ZSONArray をインポートします。
-
- java.util.List をインポートします。
-
- 静的ohos.security.SystemPermission.DISTRIBUTED_DATASYNC をインポートします。
-
- パブリッククラス MainAbilitySlice は AbilitySlice を拡張します {
- // データを表示
- プライベートテキストテキスト;
- // 分散データベースマネージャー
- プライベート KvManager kvManager;
- // 分散データベース
- プライベート SingleKvStore シングルKvストア;
- // データベース名
- プライベート静的最終文字列 STORE_NAME = "MyStore" ;
- // 保存するデータキー
- プライベート静的最終文字列 KEY_COUNT = "key_count" ;
-
- @オーバーライド
- パブリックvoid onStart(インテント インテント) {
- super.onStart(インテント);
- UIContent をスーパーに設定します。
- リクエストパーミッション();
- データベースを初期化します。
- コンポーネントを初期化します。
- }
-
- /**
- * 分散権限を要求する
- */
- プライベートvoid requestPermission() {
- if (verifySelfPermission(DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) {
- (DISTRIBUTED_DATASYNCの許可をリクエストできる場合){
- requestPermissionsFromUser(新しい文字列[]{DISTRIBUTED_DATASYNC}, 0);
- }
- }
- }
-
- /**
- * 分散データベースを初期化する
- */
- プライベートvoid initDatabase() {
- // 分散データベースマネージャーを作成する
- kvManager = KvManagerFactory.getInstance().createKvManager(新しい KvManagerConfig(this));
-
- // データベース構成
- オプション options = new Options();
- options.setCreateIfMissing( true ) // データベースが存在しない場合に作成するかどうかを設定します
- .setEncrypt( false ) // データベースが暗号化されているかどうかを設定します
- .setKvStoreType(KvStoreType.SINGLE_VERSION); //データベースタイプ
- // 分散データベースを作成する
- 単一の KvStore = kvManager.getKvStore(オプション、STORE_NAME);
- //データベースデータの変更を監視する
- 単一のKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_ALL、新しいKvStoreObserver() {
- @オーバーライド
- パブリックvoid onChange(ChangeNotification changeNotification) {
- リスト<Entry> insertEntries = changeNotification.getInsertEntries();
- リスト<エントリ> updateEntries = changeNotification.getUpdateEntries();
-
- // 初めてデータを保存するときは、insertEntries を取得します
- ( insertEntries.size () > 0)の場合{
- for (エントリ entry : insertEntries) {
- KEY_COUNTがentry.getKey()と等しい場合{
- // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
- getUITaskDispatcher().syncDispatch(() -> {
- 整数 カウント= entry.getValue().getInt();
- text.setText( "データ: " + count );
- });
- }
- }
- }そうでない場合( updateEntries.size () > 0) {
- for (エントリ entry : updateEntries) {
- KEY_COUNTがentry.getKey()と等しい場合{
- // コールバックは非UIスレッドであり、UIはUIスレッドで更新される必要がある
- getUITaskDispatcher().syncDispatch(() -> {
- 整数 カウント= entry.getValue().getInt();
- text.setText( "データ: " + count );
- });
- }
- }
- }
- }
- });
-
- }
-
- /**
- * コンポーネントを初期化する
- */
- プライベートvoid initComponent() {
- テキスト = (テキスト) findComponentById(ResourceTable.Id_text);
- ボタン button = (Button) findComponentById(ResourceTable.Id_button);
-
- // クリックイベント
- button.setClickedListener(コンポーネント -> {
- 試す {
- 整数 カウント= singleKvStore.getInt(KEY_COUNT);
- 単一のKvStore.putInt(KEY_COUNT、カウント+1);
- } キャッチ (KvStoreException e) {
- e.printStackTrace();
- // 見つかりません、最初のエントリ
- (e.getKvStoreErrorCode() == KvStoreErrorCode.KEY_NOT_FOUND) の場合 {
- 整数 カウント= 0;
- 単一のKvStore.putInt(KEY_COUNT、カウント+1);
- }
- }
- });
- }
- }
コメントは非常に詳細で、主に次の 2 つの点に注目してください。 - キーが見つからない状況に対処するために、データを取得するときにtry catchブロックを追加します。
- データベース データ変更監視コールバックは非 UI スレッドです。 UI を更新する場合は、UI スレッドに切り替える必要があります。
上記の簡単なケースは、複数のデバイス上の同じアプリケーション間で同じデータベースを使用する分散データ サービスをすぐに習得するのに役立ちます。 詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ https://harmonyos..com |