
鸿蒙5分布式计算实战:多设备协同Todo应用开发
在鸿蒙5的分布式能力支持下,开发者可以轻松构建跨设备协同的应用。本文将带你实现一个基于ArkCompiler的分布式Todo应用,支持在手机、平板、智慧屏等多设备间同步任务列表。
一、分布式能力概述
鸿蒙5的分布式能力主要包括:
分布式软总线:设备间通信的基础设施
分布式数据管理:跨设备数据同步
分布式任务调度:跨设备任务迁移
设备虚拟化:将其他设备能力虚拟化为本地资源
二、项目结构设计
DistributedTodo/
├── entry/
│ ├── src/
│ │ ├── main/
│ │ │ ├── ets/
│ │ │ │ ├── components/ # 公共组件
│ │ │ │ ├── model/ # 数据模型
│ │ │ │ ├── pages/ # 页面
│ │ │ │ ├── utils/ # 工具类
│ │ │ │ └── ability/ # 分布式能力封装
三、核心代码实现
- 数据模型定义
// model/TodoItem.ts
export class TodoItem {
id: string = generateUUID()
content: string = ‘’
completed: boolean = false
createTime: number = Date.now()
updateTime: number = Date.now()
deviceId: string = ‘’ // 记录创建设备
constructor(content: string) {
this.content = content
}
}
function generateUUID(): string {
return ‘xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx’.replace(/[xy]/g, function© {
const r = Math.random() * 16 | 0
const v = c === ‘x’ ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}
2. 分布式数据管理封装
// ability/DistributedDataManager.ts
import distributedData from ‘@ohos.data.distributedData’
import deviceInfo from ‘@ohos.distributedHardware.deviceInfo’
class DistributedDataManager {
private kvManager: distributedData.KVManager
private kvStore: distributedData.KVStore
private storeId: string = ‘distributed_todo_store’
// 初始化分布式数据库
async initKVStore(): Promise<void> {
const context = getContext(this)
const config = {
bundleName: context.applicationInfo.name,
userInfo: {
userId: ‘default’ // 实际项目应根据用户体系设置
}
}
// 1. 创建KVManager实例
this.kvManager = distributedData.createKVManager(config)
// 2. 获取设备列表
const deviceList = deviceInfo.getAvailableDeviceListSync()
console.log('可用设备:', deviceList)
// 3. 创建KVStore
const options = {
createIfMissing: true,
encrypt: false,
backup: false,
autoSync: true,
kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
schema: ''
}
this.kvStore = await this.kvManager.getKVStore(this.storeId, options)
// 4. 订阅数据变化
this.kvStore.on('dataChange', distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, (data) => {
console.log('数据变化:', data)
AppStorage.SetOrCreate('todoUpdateTime', Date.now()) // 通知UI更新
})
}
// 添加或更新Todo项
async putTodoItem(item: TodoItem): Promise<void> {
if (!this.kvStore) {
await this.initKVStore()
}
item.updateTime = Date.now()
await this.kvStore.put(item.id, JSON.stringify(item))
}
// 删除Todo项
async deleteTodoItem(id: string): Promise<void> {
if (!this.kvStore) {
await this.initKVStore()
}
await this.kvStore.delete(id)
}
// 获取所有Todo项
async getAllTodoItems(): Promise<TodoItem[]> {
if (!this.kvStore) {
await this.initKVStore()
}
const entries = await this.kvStore.getEntries(‘’)
const items: TodoItem[] = []
for (let i = 0; i < entries.length; i++) {
const item = JSON.parse(entries[i].value as string) as TodoItem
items.push(item)
}
return items.sort((a, b) => b.updateTime - a.updateTime)
}
}
export const dataManager = new DistributedDataManager()
3. 主页面实现
// pages/Index.ets
import { TodoItem } from ‘…/model/TodoItem’
import { dataManager } from ‘…/ability/DistributedDataManager’
@Entry
@Component
struct Index {
@State todoList: TodoItem[] = []
@State newTodoContent: string = ‘’
@StorageLink(‘todoUpdateTime’) updateTime: number = 0
aboutToAppear() {
this.loadTodoList()
}
async loadTodoList() {
this.todoList = await dataManager.getAllTodoItems()
}
build() {
Column() {
// 标题栏
Row() {
Text(‘分布式Todo’)
.fontSize(24)
.fontWeight(FontWeight.Bold)
Button('刷新')
.margin({ left: 20 })
.onClick(() => {
this.loadTodoList()
})
}
.width('100%')
.justifyContent(FlexAlign.Start)
.padding(20)
// 新增Todo输入框
Row() {
TextInput({ placeholder: '输入新任务', text: this.newTodoContent })
.onChange((value: string) => {
this.newTodoContent = value
})
.layoutWeight(1)
Button('添加')
.margin({ left: 10 })
.onClick(async () => {
if (this.newTodoContent.trim()) {
const newItem = new TodoItem(this.newTodoContent)
newItem.deviceId = deviceInfo.deviceId // 记录设备ID
await dataManager.putTodoItem(newItem)
this.newTodoContent = ''
this.loadTodoList()
}
})
}
.width('100%')
.padding(20)
// Todo列表
List({ space: 10 }) {
ForEach(this.todoList, (item: TodoItem) => {
ListItem() {
TodoItemView({ item: item })
}
}, (item: TodoItem) => item.id)
}
.layoutWeight(1)
.width('100%')
}
.width('100%')
.height('100%')
.onChange(() => {
// 当updateTime变化时重新加载列表
this.loadTodoList()
})
}
}
@Component
struct TodoItemView {
@Prop item: TodoItem
@State isEditing: boolean = false
@State editContent: string = ‘’
build() {
Row() {
// 完成状态复选框
Checkbox()
.select(this.item.completed)
.onChange((checked: boolean) => {
this.item.completed = checked
this.item.updateTime = Date.now()
dataManager.putTodoItem(this.item)
})
// 任务内容
if (this.isEditing) {
TextInput({ text: this.editContent })
.onChange((value: string) => {
this.editContent = value
})
.layoutWeight(1)
} else {
Text(this.item.content)
.decoration({ type: this.item.completed ? TextDecorationType.LineThrough : TextDecorationType.None })
.layoutWeight(1)
}
// 操作按钮
if (this.isEditing) {
Button('保存')
.margin({ left: 10 })
.onClick(async () => {
this.item.content = this.editContent
this.item.updateTime = Date.now()
await dataManager.putTodoItem(this.item)
this.isEditing = false
})
} else {
Button('编辑')
.margin({ left: 10 })
.onClick(() => {
this.editContent = this.item.content
this.isEditing = true
})
}
Button('删除')
.margin({ left: 10 })
.onClick(async () => {
await dataManager.deleteTodoItem(this.item.id)
})
}
.width('100%')
.padding(10)
.borderRadius(10)
.backgroundColor(Color.White)
.shadow({ radius: 2, color: '#888', offsetX: 1, offsetY: 1 })
}
}
4. 设备协同能力扩展
// ability/DeviceCollaboration.ts
import distributedMissionManager from ‘@ohos.distributedMissionManager’
import deviceInfo from ‘@ohos.distributedHardware.deviceInfo’
class DeviceCollaboration {
// 获取附近设备列表
async getNearbyDevices(): Promise<deviceInfo.DeviceInfo[]> {
return deviceInfo.getAvailableDeviceListSync()
}
// 迁移任务到其他设备
async migrateTask(deviceId: string, todoItem: TodoItem): Promise<void> {
const mission = {
todoItem: todoItem,
action: ‘edit’
}
try {
await distributedMissionManager.startMission({
deviceId: deviceId,
mission: JSON.stringify(mission),
callback: (err) => {
if (err) {
console.error('任务迁移失败:', err)
} else {
console.log('任务已迁移到设备:', deviceId)
}
}
})
} catch (err) {
console.error('任务迁移异常:', err)
}
}
}
export const deviceCollab = new DeviceCollaboration()
四、权限配置
在module.json5中添加必要的权限:
{
“module”: {
“requestPermissions”: [
{
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”,
“reason”: “分布式数据同步”
},
{
“name”: “ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE”,
“reason”: “监听设备状态变化”
},
{
“name”: “ohos.permission.GET_DISTRIBUTED_DEVICE_INFO”,
“reason”: “获取分布式设备信息”
}
]
}
}
五、应用效果
多设备实时同步:在一台设备上添加/修改/删除任务,其他设备会自动更新
任务迁移:可以将任务迁移到其他设备继续编辑
设备标识:每个任务会记录创建设备信息
离线支持:设备离线时数据本地保存,联网后自动同步
六、总结
通过鸿蒙5的分布式能力,我们实现了一个真正的多设备协同Todo应用:
使用分布式数据管理实现数据自动同步
通过分布式任务调度支持任务迁移
利用设备虚拟化获取周边设备信息
采用KV数据库保证数据一致性
