超级终端多设备协同开发
基础概念
1. 超级终端多设备协同定义
超级终端多设备协同是 HarmonyOS Next 推出的一种全新的应用形态,具有以下特点:
- 多设备联动:通过超级终端,用户可以将手机、平板、智慧屏、手表等设备连接在一起;
- 无缝体验:在多设备间实现应用迁移、数据同步、任务共享;
- 场景化应用:针对特定业务场景设计,提供单一功能;
- 跨设备操作:支持在多设备间进行文件传输、视频通话、游戏互动等操作。
2. 架构组成
超级终端多设备协同采用分布式架构,由以下部分组成:
- 分布式数据管理:负责数据的存储、同步与共享;
- 分布式通信:负责设备间的通信与数据传输;
- 分布式任务调度:负责任务的分配与执行;
- 分布式 UI 组件:负责多设备间的 UI 布局与交互。
实战步骤
1. 项目结构调整
在 entry/src/main/ets 目录下创建以下文件夹:
distributed:存放分布式能力相关代码;ui:存放分布式 UI 组件相关代码。
2. 分布式数据管理实现
工具类
entry/src/main/ets/utils/DistributedDataManager.ets
import dataShare from '@ohos.data.dataShare';
import { UIAbilityContext } from '@ohos.abilityAccessCtrl';
// 分布式数据管理工具类
export class DistributedDataManager {
private static instance: DistributedDataManager | null = null;
private dataShareHelper: dataShare.DataShareHelper | null = null;
// 单例模式
static getInstance(): DistributedDataManager {
if (!DistributedDataManager.instance) {
DistributedDataManager.instance = new DistributedDataManager();
}
return DistributedDataManager.instance;
}
// 初始化分布式数据管理
async init(context: UIAbilityContext): Promise<void> {
if (!this.dataShareHelper) {
const uri = 'dataability://com.example.myapp';
this.dataShareHelper = await dataShare.createDataShareHelper(context, uri);
}
}
// 保存数据
async saveData(key: string, value: any): Promise<void> {
if (!this.dataShareHelper) return;
await this.dataShareHelper.insert('data', { key, value });
}
// 获取数据
async getData(key: string): Promise<any> {
if (!this.dataShareHelper) return null;
const result = await this.dataShareHelper.query('data', { key });
if (result && result.length > 0) {
return result[0].value;
}
return null;
}
// 删除数据
async deleteData(key: string): Promise<void> {
if (!this.dataShareHelper) return;
await this.dataShareHelper.delete('data', { key });
}
// 监听数据变化
onDataChange(key: string, callback: (value: any) => void): void {
if (!this.dataShareHelper) return;
this.dataShareHelper.on('dataChange', (data: any) => {
if (data.key === key) {
callback(data.value);
}
});
}
// 取消监听数据变化
offDataChange(key: string, callback: (value: any) => void): void {
if (!this.dataShareHelper) return;
this.dataShareHelper.off('dataChange', callback);
}
}
应用示例
entry/src/main/ets/services/SearchService.ets
import { DistributedDataManager } from '../utils/DistributedDataManager';
// 搜索服务
export class SearchService {
// 保存搜索记录
async saveSearchHistory(keyword: string): Promise<void> {
const history = await this.getSearchHistory();
const index = history.findIndex(item => item === keyword);
if (index !== -1) {
history.splice(index, 1);
}
history.unshift(keyword);
if (history.length > 10) {
history.splice(10);
}
await DistributedDataManager.getInstance().saveData('searchHistory', history);
}
// 获取搜索记录
async getSearchHistory(): Promise<Array<string>> {
const history = await DistributedDataManager.getInstance().getData('searchHistory');
return history || [];
}
// 删除搜索记录
async deleteSearchHistory(keyword: string): Promise<void> {
const history = await this.getSearchHistory();
const index = history.findIndex(item => item === keyword);
if (index !== -1) {
history.splice(index, 1);
await DistributedDataManager.getInstance().saveData('searchHistory', history);
}
}
// 清空搜索记录
async clearSearchHistory(): Promise<void> {
await DistributedDataManager.getInstance().deleteData('searchHistory');
}
}
entry/src/main/ets/services/CartService.ets
import { DistributedDataManager } from '../utils/DistributedDataManager';
// 购物车服务
export class CartService {
// 添加商品到购物车
async addToCart(productId: number, count: number): Promise<void> {
const cartItems = await this.getCartItems();
const index = cartItems.findIndex(item => item.productId === productId);
if (index !== -1) {
cartItems[index].count += count;
} else {
// 假设 goodsData 已在外部定义
const product = goodsData.find(item => item.id === productId);
if (product) {
cartItems.push({ id: productId, productId, name: product.name, imageUrl: product.imageUrl, price: product.price, count, isChecked: false });
}
}
await this.saveCartItems(cartItems);
// 同步到分布式数据管理
await DistributedDataManager.getInstance().saveData('cartItems', cartItems);
}
// 获取购物车商品
async getCartItems(): Promise<Array<CartItemModel>> {
// 先从分布式数据管理获取
const remoteData = await DistributedDataManager.getInstance().getData('cartItems');
if (remoteData) return remoteData;
// 分布式数据管理无数据,从本地数据库获取
const localData = await this.getCartItemsFromLocal();
return localData;
}
// 删除购物车商品
async deleteCartItem(id: number): Promise<void> {
const cartItems = await this.getCartItems();
const index = cartItems.findIndex(item => item.id === id);
if (index !== -1) {
cartItems.splice(index, 1);
await this.saveCartItems(cartItems);
// 同步到分布式数据管理
await DistributedDataManager.getInstance().saveData('cartItems', cartItems);
}
}
// 清空购物车
async clearCart(): Promise<void> {
await this.saveCartItems([]);
// 同步到分布式数据管理
await DistributedDataManager.getInstance().saveData('cartItems', []);
}
}
3. 分布式通信实现
工具类
entry/src/main/ets/utils/DistributedCommunicationManager.ets
import communication from '@ohos.comm';
import { UIAbilityContext } from '@ohos.abilityAccessCtrl';
// 分布式通信工具类
export class DistributedCommunicationManager {
private static instance: DistributedCommunicationManager | null = null;
private communicationHelper: communication.CommunicationHelper | null = null;
// 单例模式
static getInstance(): DistributedCommunicationManager {
if (!DistributedCommunicationManager.instance) {
DistributedCommunicationManager.instance = new DistributedCommunicationManager();
}
return DistributedCommunicationManager.instance;
}
// 初始化分布式通信
async init(context: UIAbilityContext): Promise<void> {
if (!this.communicationHelper) {
this.communicationHelper = communication.createCommunicationHelper(context);
}
}
// 发现设备
onDeviceFound(callback: (device: communication.DeviceInfo) => void): void {
if (!this.communicationHelper) return;
this.communicationHelper.on('deviceFound', (device: communication.DeviceInfo) => {
callback(device);
});
}
// 取消发现设备
offDeviceFound(callback: (device: communication.DeviceInfo) => void): void {
if (!this.communicationHelper) return;
this.communicationHelper.off('deviceFound', callback);
}
// 连接设备
async connectDevice(deviceId: string): Promise<boolean> {
if (!this.communicationHelper) return false;
const result = await this.communicationHelper.connect(deviceId);
return result === communication.ConnectResult.SUCCESS;
}
// 断开设备连接
async disconnectDevice(deviceId: string): Promise<boolean> {
if (!this.communicationHelper) return false;
const result = await this.communicationHelper.disconnect(deviceId);
return result === communication.DisconnectResult.SUCCESS;
}
// 发送消息
async sendMessage(deviceId: string, message: string): Promise<boolean> {
if (!this.communicationHelper) return false;
const result = await this.communicationHelper.sendMessage(deviceId, message);
return result === communication.SendResult.SUCCESS;
}
// 接收消息
onMessageReceived(callback: (deviceId: string, message: string) => void): void {
if (!this.communicationHelper) return;
this.communicationHelper.on('messageReceived', (deviceId: string, message: string) => {
callback(deviceId, message);
});
}
// 取消接收消息
offMessageReceived(callback: (deviceId: string, message: string) => void): void {
if (!this.communicationHelper) return;
this.communicationHelper.off('messageReceived', callback);
}
}
组件示例
entry/src/main/ets/components/DeviceListComponent.ets
import { DistributedCommunicationManager } from '../utils/DistributedCommunicationManager';
import { communication } from '@ohos.comm';
@Component
export struct DeviceListComponent {
@State deviceList: Array<communication.DeviceInfo> = [];
@State connectedDeviceId: string = '';
build() {
Column({ space: 16 }) {
Text('已连接设备').fontSize(18).fontWeight(FontWeight.Bold).textColor('#000000');
List({ space: 16 }) {
ForEach(this.deviceList, (device: communication.DeviceInfo) => {
ListItem() {
Row({ space: 16 }) {
Image(device.icon).width(40).height(40).objectFit(ImageFit.Contain);
Column({ space: 8 }) {
Text(device.name).fontSize(14).fontWeight(FontWeight.Bold).textColor('#000000');
Text(device.type).fontSize(14).textColor('#666666');
}.layoutWeight(1);
if (device.id === this.connectedDeviceId) {
Text('已连接').fontSize(14).textColor('#007DFF');
} else {
Button('连接').width(80).height(40).backgroundColor('#007DFF').onClick(async () => {
const result = await DistributedCommunicationManager.getInstance().connectDevice(device.id);
if (result) {
this.connectedDeviceId = device.id;
}
});
}
}.width('100%').height('auto').padding(16).backgroundColor('#FFFFFF').borderRadius(12);
}.width('100%').height('auto');
}, (device: communication.DeviceInfo) => device.id);
}.width('100%').height('auto').padding(16);
Text('可连接设备').fontSize(18).fontWeight(FontWeight.Bold).textColor('#000000');
List({ space: 16 }) {
// 可连接设备列表
}.width('100%').height('auto').padding(16);
}.width('100%').height('100%').backgroundColor('#F5F5F5');
}
aboutToAppear() {
// 监听设备发现
DistributedCommunicationManager.getInstance().onDeviceFound((device: communication.DeviceInfo) => {
this.deviceList.push(device);
});
}
}
配置与部署
1. 配置文件修改
在 entry/src/main/module.json5 中添加分布式能力配置:
{
"module": {
"requestPermissions": [
{ "name": "ohos.permission.DISTRIBUTED_DATASYNC" },
{ "name": "ohos.permission.DISTRIBUTED_COMMUNICATION" },
{ "name": "ohos.permission.GET_NETWORK_INFO" },
{ "name": "ohos.permission.READ_EXTERNAL_STORAGE" },
{ "name": "ohos.permission.WRITE_EXTERNAL_STORAGE" }
],
"abilities": [],
"widgets": [],
"pages": []
}
}
2. 项目部署
- 编译项目:在 DevEco Studio 中点击 Build → Build HAP,编译项目。
- 部署到设备:将编译后的 HAP 文件部署到鸿蒙设备上。
- 测试多设备协同:
- 在手机上打开应用,搜索商品,查看商品详情;
- 在平板上打开应用,查看购物车商品;
- 在智慧屏上打开应用,查看购物车商品。
效果验证
- 多设备协同:手机上搜索商品,平板上查看商品详情;
- 数据同步:购物车数据在多设备间同步;
- 设备发现:自动发现附近的鸿蒙设备;
- 设备连接:手动连接附近的鸿蒙设备。
总结
本文完成了超级终端多设备协同的定义与架构介绍,实现了商品搜索与购物车两个核心业务场景的多设备协同。涵盖了分布式数据管理与分布式通信的原理与实现方式,以及多设备协同的设备发现与连接流程。


