🙆

HarmonyOS 運動プロジェクト開発:プロジェクトの実行環境スイッチャー

に公開

##HarmonyOS 核心技術##運動開発#

HarmonyOS 運動プロジェクトを開発する際、異なる実行環境(開発環境、テスト環境、本番環境など)を管理することは一般的なニーズです。実行環境を適切に切り替えることで、開発者はデバッグ、テスト、デプロイを簡単に実行できます。本稿では、プロジェクトの実行環境スイッチャーの実装方法について紹介し、HarmonyOS 開発で異なる環境の設定を効率的に管理するお手伝いをします。

まえがき

現代のソフトウェア開発において、環境管理はアプリケーションの安定性と保守性を確保するための鍵となる要素の 1 つです。開発環境、テスト環境、本番環境それぞれにおいて、API のアドレス、ログレベル、機能のオン / オフなど、異なる設定が必要になる場合があります。実行環境スイッチャーを実装することで、コードを変更せずに簡単に異なる環境間を切り替えることができ、開発効率と柔軟性を高めることができます。

![イメージ説明](<url id="d1ganccqdqeu2nnlcr9g" type="url" status="failed" title="" wc="0">https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzg3tq6ad9c6l45wd3lc.jpg</url> )

  1. 環境スイッチャーの設計

(1)環境設定の種類

異なる環境の設定をサポートするために、EnvironmentConfigsCurrentEnvironment の型を定義しました。

export type EnvironmentConfigs = Map<string, Map<string, string>>;

export interface CurrentEnvironment {
  name: string;
  configs: Map<string, string>;
}

コアポイントの解説:

  1. EnvironmentConfigs:環境名(productiondevelopment など)をキーとし、その環境の設定マップを値とするマップです。
  2. CurrentEnvironment:現在の環境の名前と設定を表します。

(2)環境タイプの列挙型

サポートする環境タイプを列挙型で定義しました。

export enum EnvironmentType {
  TYPE_PRODUCTION = "production",
  TYPE_DEVELOP = "develop"
}

コアポイントの解説:

  1. 列挙型:列挙型を使用して、本番環境(production)と開発環境(develop)の 2 種類の環境タイプを定義しました。必要に応じて、さらに多くの環境タイプを追加することができます。

(3)環境管理クラス

環境管理クラス Environment は、環境スイッチャーのコアです。環境設定の格納、保存された環境の読み込み、環境の切り替え、コールバックの通知などを行います。

export class Environment {
  private static instance: Environment;
  private static readonly ENVIRONMENT_STORAGE_KEY = 'current_environment';

  private currentEnvironment?: CurrentEnvironment;
  private environments: EnvironmentConfigs = new Map();
  private preferences: LibPreferencesSync;
  private environmentChangeCallbacks: Array<(newEnvironment: CurrentEnvironment) => void> = [];

  private constructor() {
    this.preferences = new LibPreferencesSync();
  }

  public static getInstance(): Environment {
    if (!Environment.instance) {
      Environment.instance = new Environment();
    }
    return Environment.instance;
  }

  public initEnvironments(evn: EnvironmentConfigs) {
    this.environments = evn;
    this.loadSavedEnvironment();
  }

  private loadSavedEnvironment() {
    if (!IS_PRODUCTION) {
      const savedEnvironmentName = this.preferences.getValue(Environment.ENVIRONMENT_STORAGE_KEY) as string;
      if (savedEnvironmentName && this.environments.has(savedEnvironmentName)) {
        this.currentEnvironment = {
          name: savedEnvironmentName,
          configs: this.environments.get(savedEnvironmentName)!
        };
      } else {
        this.currentEnvironment = {
          name: EnvironmentType.TYPE_DEVELOP,
          configs: this.environments.get(EnvironmentType.TYPE_DEVELOP)!
        };
      }
    } else {
      this.currentEnvironment = {
        name: EnvironmentType.TYPE_PRODUCTION,
        configs: this.environments.get(EnvironmentType.TYPE_PRODUCTION)!
      };
    }
  }

  public switchEnvironment(name: string) {
    const configs = this.environments.get(name);
    if (configs) {
      this.currentEnvironment = { name, configs };
      this.preferences.saveKeyValue(Environment.ENVIRONMENT_STORAGE_KEY, name);
      this.environmentChangeCallbacks.forEach(callback => callback(this.currentEnvironment!));
    }
  }

  public getCurrentEnvironment(): CurrentEnvironment {
    return this.currentEnvironment!;
  }

  public getAllEnvironmentNames(): string[] {
    return Array.from(this.environments.keys());
  }

  public registerEnvironmentChangeCallback(callback: (newEnvironment: CurrentEnvironment) => void) {
    this.environmentChangeCallbacks.push(callback);
  }

  public unregisterEnvironmentChangeCallback(callback: (newEnvironment: CurrentEnvironment) => void) {
    this.environmentChangeCallbacks = this.environmentChangeCallbacks.filter(cb => cb !== callback);
  }
}

コアポイントの解説:

  1. シングルトンパターン:getInstance メソッドを使用して、Environment のグローバルな一意性を保証します。

  2. 環境の初期化:initEnvironments メソッドを使用して環境設定を初期化します。

  3. 保存された環境の読み込み:loadSavedEnvironment メソッド内で、保存された環境名に応じて対応する環境設定を読み込みます。

  4. 環境の切り替え:switchEnvironment メソッドを使用して環境を切り替え、登録されたすべてのコールバック関数に通知します。

  5. コールバックメカニズム:環境変更コールバックの登録と解除をサポートし、環境が変更された際に関連する操作を実行することができます。

  6. 環境スイッチャーの使用

(1)環境切り替えダイアログ

ユーザーが簡単に環境を切り替えることができるように、環境切り替えダイアログ EnvironmentDialog を実装しました。

@CustomDialog
export struct EnvironmentDialog {
  public controller: CustomDialogController;
  private themeManager: ThemeManager = ThemeManager.getInstance();
  private environment: Environment = Environment.getInstance();
  public onEnvironmentChanged?: () => void;

  build() {
    Column() {
      Text('環境を選択')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor(this.themeManager.getTextPrimaryColor())
        .margin({ top: 24, bottom: 16 })

      List() {
        ForEach(this.environment.getAllEnvironmentNames(), (envname: string) => {
          ListItem() {
            Row() {
              Column() {
                Text(envname)
                  .fontSize(16)
                  .fontColor(this.themeManager.getTextPrimaryColor())
                  .margin({ bottom: 4 })
              }
              .alignItems(HorizontalAlign.Start)
              .layoutWeight(1)

              if (this.environment.getCurrentEnvironment().name === envname) {
                Image($r('app.media.base_icon_select'))
                  .width(24)
                  .height(24)
                  .margin({ left: 8 })
              }
            }
            .width('100%')
            .padding(16)
            .backgroundColor(this.themeManager.getSurfaceColor())
            .borderRadius(8)
            .onClick(() => {
              this.environment.switchEnvironment(envname);
              this.onEnvironmentChanged?.();
              this.controller.close();
            })
          }
          .margin({ bottom: 8 })
        }, (envname: string) => envname)
      }
      .width('100%')
      .layoutWeight(1)

      Button('閉じる')
        .width('100%')
        .height(48)
        .backgroundColor(this.themeManager.getPrimaryColor())
        .margin({ top: 16 })
        .onClick(() => {
          this.controller.close();
        })
    }
    .width('90%')
    .padding(16)
    .backgroundColor(this.themeManager.getBackgroundColor())
    .borderRadius(16)
  }
}

コアポイントの解説:

  1. 環境リスト:ForEach を使用してすべての環境名を繰り返し、各環境ごとにリスト項目を生成します。
  2. 現在の環境の識別:現在の環境がリスト項目の環境と一致する場合は、選択アイコンを表示します。
  3. 環境の切り替え:リスト項目をクリックすると、switchEnvironment メソッドを使用して環境を切り替え、ダイアログを閉じます。
  4. コールバック通知:環境が切り替わると、onEnvironmentChanged コールバック関数を呼び出し、外部に環境が変更されたことを通知します。

(2)環境変更のコールバックメカニズム

環境が変更された際に関連する操作を実行するためには、コールバック関数を登録することで実現できます。

const environment = Environment.getInstance();

environment.registerEnvironmentChangeCallback((newEnvironment) => {
  console.log(`環境が切り替わりました: ${newEnvironment.name}`);
  // ここで環境が変更された後の関連する操作を実行します。例えば、設定を再読み込み、画面を更新するなど。
});

コアポイントの解説:

  1. コールバックの登録:registerEnvironmentChangeCallback メソッドを使用してコールバック関数を登録します。

  2. コールバックの実行:環境が変更された際に、自動的にコールバック関数が呼び出されます。

  3. まとめ

プロジェクトの実行環境スイッチャーを実装することで、HarmonyOS 運動プロジェクトで簡単に異なる環境の設定を管理することができるようになりました。環境スイッチャーは、環境を動的に切り替えられるだけでなく、コールバックメカニズムも提供しているため、環境が変更された際に関連する操作を実行することができます。この方法により、開発者はコードを変更せずに開発環境、テスト環境、本番環境を迅速に切り替えることができ、開発効率と柔軟性を高めることができます。

実際の開発では、プロジェクトの具体的なニーズに応じて、さらに環境スイッチャーを拡張や最適化することができます。例えば:

  • より多くの環境タイプをサポートする:プロジェクトのニーズに応じて、テスト環境、プレリリース環境など、さらに多くの環境タイプを追加することができます。
  • 設定を動的に読み込む:リモートサーバーから環境設定を動的に読み込むことができます。
  • ビルドツールに統合する:環境スイッチャーをビルドツールに統合し、ビルド時に実行環境を指定できるようにすることができます。

本稿が、あなたの HarmonyOS 開発の旅に価値ある参考となることを願っています!質問や提案があれば、いつでも交流してください。

Discussion