鴻蒙學習實戰之路-多端交互最佳實踐

多端交互是 HarmonyOS 應用開發中的重要特性,本文將介紹如何在鴻蒙應用中實現多端設備之間的高效交互,包括跨設備通信、數據共享、協同操作等內容。

關於本文

自己學習並使用 HarmonyOS 多端交互的記錄,旨在幫助小夥伴們少走彎路

華為開發者聯盟-多端交互文檔永遠是你的好夥伴,請收藏!

  • 本文並不能代替官方文檔,所有的內容也都是基於官方文檔+自己嘗試的記錄。
  • 基本所有章節基本都會附上對應的文檔鏈接,強烈建議你點看看看
  • 所有結合代碼操作的部分,建議自己動手嘗試一下

代碼測試環境

環境/工具

版本/説明

DevEco Studio

5.0.3.400

HarmonyOS SDK

API Version 12

Node.js

18.19.0

測試設備

HarmonyOS 4.0+ 模擬器

1. 概述

在 HarmonyOS 分佈式系統中,多端交互是實現設備協同的核心技術。通過多端交互,用户可以在不同設備之間無縫切換任務、共享數據和協同操作,極大提升了用户體驗。

1.1 多端交互基本概念

在 HarmonyOS 中,多端交互支持多種輸入設備,如圖 1 所示:

圖1 輸入設備


鴻蒙學習實戰之路-多端交互最佳實踐_JSON

多端交互是指在 HarmonyOS 分佈式系統中,不同設備之間通過分佈式能力框架進行通信和協作的技術。

1.2 多端交互的應用場景

  • 跨設備任務遷移:用户可以在手機上開始編輯文檔,然後無縫切換到平板繼續編輯
  • 多屏協同:手機與平板、電腦等設備協同工作,擴展顯示和操作空間
  • 數據共享:照片、文檔等數據在不同設備之間實時共享
  • 設備聯動:智能家居設備之間的聯動控制,如手機控制智能電視、智能音箱等

2. 分佈式能力框架

HarmonyOS 提供了完整的分佈式能力框架,用於支持多端設備之間的交互。

2.1 分佈式能力框架概述

分佈式能力框架包含以下核心組件:

  • 分佈式軟總線:提供設備發現、連接和通信能力
  • 分佈式數據管理:提供跨設備數據共享和同步能力
  • 分佈式任務調度:提供跨設備任務分發和遷移能力
  • 分佈式安全:提供跨設備安全認證和數據加密能力

為了更好地理解多端交互,我們可以看一個手寫筆套件的示例,如圖 2 所示:

圖2 手寫筆套件示例


鴻蒙學習實戰之路-多端交互最佳實踐_數據共享_02

2.2 配置分佈式能力

在項目的module.json5文件中添加分佈式能力相關配置:

{
  module: {
    // ...其他配置
    abilities: [
      {
        // ...其他配置
        skills: [
          {
            // ...其他配置
          },
        ],
      },
    ],
    requestPermissions: [
      {
        name: "ohos.permission.DISTRIBUTED_DATASYNC",
      },
      {
        name: "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO",
      },
    ],
  },
}

3. 設備發現與連接

在多端交互中,瞭解不同輸入設備的基礎輸入事件觸發方式非常重要,如圖 3 所示:

圖3 輸入設備基礎輸入事件觸發方式一覽表


鴻蒙學習實戰之路-多端交互最佳實踐_JSON_03

3.1 設備發現

使用分佈式軟總線 API 發現附近的設備:

import { businessError } from "@kit.BasicServicesKits";
import { distributedDeviceManager } from "@kit.DeviceManagerKit";

// 獲取分佈式設備管理器
let deviceManager = distributedDeviceManager.getDistributedDeviceManager();

// 發現設備
if (deviceManager) {
  deviceManager.startDeviceDiscovery(
    (
      discoveryMode: number,
      filterOptions: string,
      callback: (
        deviceId: string,
        deviceInfo: distributedDeviceManager.DeviceInfo
      ) => void,
      onFailure: (code: number, error: businessError.BusinessError) => void
    ) => {
      console.log("設備發現開始");
    }
  );

  // 監聽設備發現事件
  deviceManager.on(
    "deviceStateChange",
    (data: {
      action: number;
      deviceId: string;
      deviceInfo: distributedDeviceManager.DeviceInfo;
    }) => {
      console.log(`設備狀態變化: ${JSON.stringify(data)}`);
      if (
        data.action ===
        distributedDeviceManager.DeviceStateChangeAction.DEVICE_FOUND
      ) {
        console.log(`發現設備: ${data.deviceInfo.deviceName}`);
      }
    }
  );
}

3.2 設備連接

與發現的設備建立連接:

// 連接設備
if (deviceManager) {
  deviceManager.connectDevice(
    deviceId,
    (code: number, data: distributedDeviceManager.ConnectResult) => {
      if (code === 0) {
        console.log("設備連接成功");
      } else {
        console.error(`設備連接失敗: ${code}`);
      }
    }
  );
}

4. 跨設備數據共享

在多端交互中,手勢事件是重要的交互方式之一。下圖為常見手勢事件在不同輸入設備上的觸發方式,如圖 4 所示:

圖4 輸入設備手勢事件觸發方式一覽表


鴻蒙學習實戰之路-多端交互最佳實踐_數據_04

4.1 分佈式數據對象

使用分佈式數據對象實現跨設備數據共享:

import { distributedData } from "@kit.DistributedDataKit";

// 創建分佈式數據對象
let distributedObject = distributedData.createDistributedObject({
  message: "Hello HarmonyOS",
  count: 0,
});

// 監聽數據變化
distributedObject.on(
  "change",
  (data: { changedKeys: Array<string>; deviceId: string }) => {
    console.log(`數據變化: ${JSON.stringify(data)}`);
  }
);

// 更新數據
distributedObject.set("message", "Hello Distributed World");
distributedObject.set("count", distributedObject.get("count") + 1);

4.2 分佈式文件系統

使用分佈式文件系統實現跨設備文件共享:

import { distributedFS } from "@kit.DistributedFileKit";

// 獲取分佈式文件路徑
let distributedPath = distributedFS.getDistributedDir(globalThis.context);
console.log(`分佈式文件路徑: ${distributedPath}`);

// 在分佈式路徑下創建文件
let filePath = distributedPath + "/test.txt";
let fileContent = "這是一個分佈式文件示例";

distributedFS.writeFile(filePath, fileContent, (err) => {
  if (err) {
    console.error(`文件寫入失敗: ${JSON.stringify(err)}`);
  } else {
    console.log("文件寫入成功");
  }
});

5. 跨設備任務調度

在多端交互中,鍵盤交互也是重要的組成部分。下面展示了使用鍵盤走焦的示例,如圖 5 所示:

圖5 使用鍵盤走焦


鴻蒙學習實戰之路-多端交互最佳實踐_JSON_05

同時,良好的走焦樣式指引對於提升用户體驗非常重要,如圖 6 所示:

圖6 走焦樣式指引案例


鴻蒙學習實戰之路-多端交互最佳實踐_數據_06

5.1 任務遷移

將任務從當前設備遷移到目標設備:

import { distributedTask } from "@kit.DistributedTaskKit";

// 遷移任務
let taskInfo = {
  bundleName: "com.example.myapplication",
  abilityName: "EntryAbility",
  parameters: {
    key1: "value1",
    key2: "value2",
  },
};

distributedTask.migrateTaskToDevice(deviceId, taskInfo, (err) => {
  if (err) {
    console.error(`任務遷移失敗: ${JSON.stringify(err)}`);
  } else {
    console.log("任務遷移成功");
  }
});

5.2 遠程調用

調用目標設備上的能力:

import { remote } from "@kit.RemoteDeviceKit";

// 創建遠程調用會話
let session = remote.createRemoteSession(deviceId);

// 調用遠程方法
session.callRemoteMethod("remoteMethod", { param: "test" }, (err, result) => {
  if (err) {
    console.error(`遠程調用失敗: ${JSON.stringify(err)}`);
  } else {
    console.log(`遠程調用結果: ${JSON.stringify(result)}`);
  }
  // 關閉會話
  session.close();
});

6. 多端交互最佳實踐

6.1 場景一:跨設備文檔編輯

實現思路:

  1. 使用分佈式數據對象同步文檔內容
  2. 使用分佈式任務調度實現編輯任務遷移
  3. 使用分佈式安全確保文檔內容安全
// 文檔編輯示例
import { distributedData } from '@kit.DistributedDataKit';

@Component
export struct DistributedDocumentEditor {
  // 創建分佈式文檔對象
  private docObject = distributedData.createDistributedObject({
    content: '',
    cursorPosition: 0,
    lastEditTime: 0
  });

  @State localContent: string = '';

  build() {
    Column() {
      TextInput({
        text: this.localContent,
        placeholder: '開始編輯文檔...'
      })
      .width('100%')
      .height(300)
      .onChange((value: string) => {
        this.localContent = value;
        // 同步到分佈式數據對象
        this.docObject.set('content', value);
        this.docObject.set('lastEditTime', Date.now());
      })

      Button('同步到其他設備')
      .onClick(() => {
        console.log('文檔已同步');
      })
    }
    .padding(20)
  }

  aboutToAppear() {
    // 監聽分佈式數據變化
    this.docObject.on('change', (data) => {
      if (data.changedKeys.includes('content')) {
        this.localContent = this.docObject.get('content') as string;
      }
    });
  }
}

6.2 場景二:多設備協同遊戲

實現思路:

  1. 使用分佈式軟總線實現設備間實時通信
  2. 使用分佈式數據管理同步遊戲狀態
  3. 使用分佈式任務調度協調遊戲流程
// 多設備協同遊戲示例
import { distributedData } from '@kit.DistributedDataKit';
import { distributedDeviceManager } from '@kit.DeviceManagerKit';

@Component
export struct DistributedGame {
  // 遊戲狀態
  private gameState = distributedData.createDistributedObject({
    players: [] as Array<{ deviceId: string; name: string; score: number }>,
    currentTurn: '',
    gameStatus: 'waiting' // waiting, playing, finished
  });

  @State localPlayerName: string = '玩家1';
  @State connectedDevices: Array<distributedDeviceManager.DeviceInfo> = [];

  build() {
    Column() {
      Text('多設備協同遊戲')
      .fontSize(24)
      .margin(20)

      TextInput({
        text: this.localPlayerName,
        placeholder: '輸入你的暱稱'
      })
      .width('80%')
      .margin(20)

      Button('加入遊戲')
      .onClick(() => {
        this.joinGame();
      })

      Text('已連接設備:')
      .fontSize(18)
      .margin(20)

      ForEach(this.connectedDevices, (device) => {
        Text(device.deviceName)
        .padding(10)
      })

      Button('開始遊戲')
      .onClick(() => {
        this.startGame();
      })
      .margin(20)
    }
  }

  joinGame() {
    // 獲取設備管理器
    let deviceManager = distributedDeviceManager.getDistributedDeviceManager();
    if (deviceManager) {
      // 獲取本地設備信息
      let localDeviceInfo = deviceManager.getLocalDeviceInfo();

      // 添加玩家到遊戲狀態
      let players = this.gameState.get('players') as Array<{ deviceId: string; name: string; score: number }>;
      players.push({
        deviceId: localDeviceInfo.deviceId,
        name: this.localPlayerName,
        score: 0
      });

      this.gameState.set('players', players);
      this.gameState.set('gameStatus', 'waiting');

      console.log(`${this.localPlayerName} 加入了遊戲`);
    }
  }

  startGame() {
    // 設置遊戲狀態為開始
    this.gameState.set('gameStatus', 'playing');

    // 設置當前回合
    let players = this.gameState.get('players') as Array<{ deviceId: string; name: string; score: number }>;
    if (players.length > 0) {
      this.gameState.set('currentTurn', players[0].deviceId);
    }

    console.log('遊戲開始');
  }

  aboutToAppear() {
    // 監聽設備連接狀態
    let deviceManager = distributedDeviceManager.getDistributedDeviceManager();
    if (deviceManager) {
      deviceManager.on('deviceStateChange', (data) => {
        if (data.action === distributedDeviceManager.DeviceStateChangeAction.DEVICE_ONLINE) {
          this.connectedDevices.push(data.deviceInfo);
        } else if (data.action === distributedDeviceManager.DeviceStateChangeAction.DEVICE_OFFLINE) {
          this.connectedDevices = this.connectedDevices.filter(device => device.deviceId !== data.deviceId);
        }
      });
    }
  }
}

7. 多端交互性能優化

7.1 減少數據傳輸量

  • 只傳輸必要的數據字段
  • 使用壓縮算法減少數據大小
  • 批量傳輸數據,減少通信次數

7.2 優化設備發現機制

  • 使用合適的發現模式(主動/被動)
  • 設置合理的發現超時時間
  • 避免頻繁掃描設備

7.3 合理使用緩存

  • 在本地緩存常用數據
  • 減少跨設備數據查詢次數
  • 使用增量同步減少數據傳輸

8. 總結

多端交互是 HarmonyOS 分佈式能力的核心特性,通過本文的介紹,我們瞭解了:

  1. HarmonyOS 分佈式能力框架的基本組成
  2. 設備發現與連接的實現方法
  3. 跨設備數據共享的技術方案
  4. 跨設備任務調度的使用場景
  5. 多端交互的最佳實踐案例
  6. 性能優化的關鍵策略

通過合理應用這些技術,開發者可以構建出更加智能、高效的多端協同應用,為用户提供無縫的跨設備體驗。

參考文檔

  • 華為開發者聯盟-分佈式能力文檔



需要參加鴻蒙認證的請點擊 鴻蒙認證鏈接