HC 2024 开发者布道师交流区分布式作品技术分享帖
HC分布式作品技术分享帖
作者:兰州大学 学生开发者布道师 王天一、聂嘉一
1.OpenHarmony阅读器及分布式能力介绍
本作品的工作始于第一届OpenHarmony竞赛训练营行业使能赛题(题目十:OpenHarmony阅读器.md · OpenHarmony竞赛训练营),在参加HC2024学生布道师展区之前,在原作品的基础上添加了OpenHarmony分布式软总线能力,进一步提升了用户的阅读体验、体现了鸿蒙系统的重要特性之一——“硬件互助、资源共享”。
本作品主要使用了以下技术元素来实现不同设备间的组网与通信、同步拉起与数据共享:
- 使用分布式设备管理能力接口(设备管理),实现设备之间的distributedDataObject对象的数据传输交互@ohos.distributedDeviceManager
- 使用分布式数据管理接口@ohos.data.distributedData
- 使用权限管理能力@ohos.abilityAccessCtrl
- 使用分布式数据对象接口@ohos.data.distributedDataObject
本作品的分布式交互效果如下列链接中的视频所示:。
2.OpenHarmony阅读器实现
约束与限制
1.本示例仅支持标准系统上运行。
2.本示例为Stage模型,已适配API version 10版本SDK,版本号:4.0.10.13,镜像版本号:OpenHarmony4.0.10.13。
3.本示例需要使用DevEco Studio 3.1 Beta2 (Build Version: 3.1.0.400, built on April 7, 2023)及以上版本才可编译运行。
4.本示例需要使用@ohos.distributedDeviceManager系统权限的系统接口。使用Full SDK时需要手动从镜像站点获取,并在DevEco Studio中替换,具体操作可参考替换指南。
5.本示例所配置的权限均为system_basic或system_core级别(相关权限级别可通过权限定义列表查看),需要手动配置对应级别的权限签名(具体操作可查看自动化签名方案)。
6.本示例类型为系统应用,需要手动配置对应级别的应用类型(“app-feature”: “hos_system_app”)。具体可参考profile配置文件bundle-info对象内部结构。
本作品的ArkUI实现重点为分布式连接界面和阅读界面。
使用说明
- 启动应用,选择允许授权后,进入首页的分布式连接界面:
-
点击右上角按钮可以连接组网设备,选择设备后进行连接,连接成功后两个设备上首页状态均显示绿色,每次连接其他设备,界面会清空已保存的书籍记录。
-
点击添加按钮进入添加界面,可以编辑标题、介绍,点击确定按钮添加这条记录。
-
点击清除按钮清除所有书籍记录。
-
点击已经添加的备忘录可以进入编辑界面更新书籍记录,编辑完成后点击提交按钮更新书籍记录。
-
两台设备连接成功后步骤2、3、4的操作会同步到另一台设备上。
-
如选择开始阅读,则进入界面:
- 点击右上角按钮可以连接组网设备,选择设备后进行连接,连接成功后两个设备上首页状态均显示绿色。
- 两台设备连接成功后进行的翻页操作会同步到另一台设备上。
- 点击back按钮,则回退到首页。
相关概念
分布式数据对象:组网内的设备,通过创建相同sessionId的分布式数据对象,修改分布式对象时,对端设备可以监听到数据变化并获取到新的数据,从而实现不同设备间的数据交换。
3.工程目录
entry/src/main/ets/
|---pages
| |---index.ets // 首页
| |---SplashPages.ets // 应用启动动画页面
| |---IndexNote.ets // 分布式连接页面
| |---Read.ets // 阅读页面
|---MainAbility
| |---MainAbility.ts // 请求用户授权“多设备协同”能力
|---model
| |---Const.ts // 静态资源模块(书籍标记颜色的图片资源)
| |---DistributedObjectModel.ts // 分布式书籍数据对象类
| |---Note.ts // 书籍对象操作类
| |---RemoteDeviceModel.ts // 远程设备操作类
|---common
| |---BasicDataSource.ets // 初始化数据模块
| |---NoteItem.ets // 书籍列表模块
| |---DeviceDialog.ets // 分布式设备列表弹窗
| |---TitleBar.ets // 菜单栏模块
页面代码示例1:启动动画界面
.\pages\SplashPage.ets
代码功能
- 存储初始化:初始化了应用的持久化存储,将 token 设置为空字符串,并设置 currentTabIndex 的值为 0。可以通过改变currentTabIndex的值来实现页面底部导航栏页面的切换。
- 动画过渡:当页面显示时(onPageShow 方法),使用动画效果展示 Logo 和应用名称,然后通过定时器延迟一段时间后跳转到另一个页面。
- 页面构建:使用 build 方法来构建用户界面,包括一个条件渲染的 Logo 和应用名称,以及一个固定的底部文本。
代码解析
-
页面显示处理
onPageShow(){ animateTo({ duration: 1000, onFinish: () => { setTimeout(() => { router.replaceUrl({ url: 'pages/IndexNote' }); // 切换页面,且不能返回 }, 200); } }, () => { this.flag = true; }); }
当页面显示时,执行动画效果,动画结束后延迟 200 毫秒执行页面跳转。这里使用
replaceUrl
而不是普通的pushUrl
,使用户从新页面返回时不会再次触发该启动动画。 -
页面构建逻辑
build() { Column() { if (this.flag) { Image($r('app.media.ic_logo_lzu')) .logoStyle() .transition({ type: TransitionType.Insert, opacity: 0, translate: { x: -150 } }); Text("开源鸿蒙阅读器demo") .titleStyle() .transition({ type: TransitionType.Insert, opacity: 0, translate: { x: 150 } }); } Blank() Text("OpenHarmony Project") // 最底部 .footerStyle(); }.bgStyle(); }
使用条件语句来根据 flag 的值决定是否显示 Logo 和应用名称。此外,还设置了动画过渡效果来平滑地展示这些元素,底部有一个固定的文本 “OpenHarmony Project”。
**页面代码示例2:分布式连接 **
.\pages\IndexNote.ets
代码功能
- 设备管理和跨设备同步:使用
DistributedObjectModel
进行跨设备的数据共享,并且有状态变更回调机制。 - 设备选择与启动:允许用户选择一个远程设备,并启动目标设备上的能力(相当于应用中的某个功能模块)。
- 笔记数据展示与操作:展示书籍列表,并提供添加和清除笔记的功能。
- 状态指示:展示当前设备的在线状态。
代码解析
-
设备选择与启动
onSelectedDevice = (selectedIndex: number) => { this.selectedIndex = selectedIndex; Logger.info(TAG, 'start ability ......'); if (RemoteDeviceModel === null || RemoteDeviceModel.discoverDevices.length <= 0) { Logger.info(TAG, `start ability device:${JSON.stringify(this.devices)}`); this.startAbility(this.devices[this.selectedIndex].networkId as string); this.clearSelectState(); return; } Logger.info(TAG, 'start ability, needAuth'); RemoteDeviceModel.authenticateDevice(this.devices[this.selectedIndex], (device: deviceManager.DeviceBasicInfo) => { Logger.info(TAG, 'auth and online finished'); this.startAbility(device.networkId); }) Logger.info(TAG, 'start ability2 ......'); this.clearSelectState(); }
当用户选择了一个设备后,会调用 startAbility 方法来启动远程设备的能力。如果设备列表为空或者不存在,则直接启动;否则需要先认证设备。
-
笔记数据展示与操作
List({ space: 10 }) { LazyForEach(this.noteDataSource, (item: Note, index) => { ListItem() { NoteItem({ note: item, index: index }) .id(`${item.title}`) } }, (item: Note) => JSON.stringify(item)) }
这部分代码展示了笔记列表,并且使用了懒加载机制来提高性能。
-
状态指示
Row() { Text("连接状态 ") .fontWeight(FontWeight.Bold) .height(35) .fontSize(18) Image(this.isOnline ? $r('app.media.green') : $r('app.media.red')) .size({ width: 20, height: 20 }) .objectFit(ImageFit.Contain) }
这部分代码展示了当前设备的连接状态,使用绿色或红色图标表示在线或离线状态。
-
页面构建逻辑
build() { Column() { // 状态栏和其他UI元素 ... // 笔记列表 List({ space: 10 }) { LazyForEach(this.noteDataSource, (item: Note, index) => { ListItem() { NoteItem({ note: item, index: index }) .id(`${item.title}`) } }, (item: Note) => JSON.stringify(item)) } .width('95%') .margin(10) .layoutWeight(1) // 清除笔记按钮 Column() { Image($r('app.media.clear')) .size({ width: 20, height: 20 }) Text($r('app.string.clear')) .fontColor(Color.Red) .fontSize(20) }.layoutWeight(1) .id('clearNote') .onClick(() => { Logger.info(TAG, 'clear notes'); this.noteDataSource.dataArray = []; this.noteDataSource.notifyDataReload(); this.globalObject.clear(); AppStorage.SetOrCreate('sessionId', this.sessionId); }) // 添加笔记按钮 Column() { Image($r('app.media.add')) .size({ width: 20, height: 20 }) Text($r('app.string.add')) .fontColor(Color.Black) .fontSize(20) }.layoutWeight(1) .id('addNote') .onClick(() => { router.pushUrl({ url: 'pages/Edit', params: { note: new Note('', '', '', -1, 0), isAdd: true } }) }) } .width('100%') .height('100%') }
页面构建部分主要负责创建 UI 元素,包括顶部的状态栏、笔记列表以及底部的操作按钮(清除笔记和添加笔记)。每个元素都有特定的样式配置,并且添加了点击事件处理器以实现相应的功能。
相关权限
允许不同设备间的数据交换:ohos.permission.DISTRIBUTED_DATASYNC。
允许系统应用获取分布式设备的认证组网能力:ohos.permission.ACCESS_SERVICE_DM。
- 点赞
- 收藏
- 关注作者
评论(0)