分布式音乐播放器适配了Stage模型

OpenAtom OpenHarmony(以下简称“OpenHarmony”)应用开发自API 8及其更早版本一直使用的是FA模型进行开发。FA模型是Feature Ability的缩写,它和PA(Particle Ability)两种类型是过往长期推广的术语,深入人心。

然而从API 9开始,Ability框架引入了Stage模型作为第二种应用框架形态,Stage模型将Ability分为PageAbility和ExtensionAbility两大类,其中ExtensionAbility又被扩展为ServiceExtensionAbility、FormExtensionAbility、DataShareExtensionAbility等一系列ExtensionAbility,以便满足更多的使用场景。新模型接口中有AbilityStage/WindowStage的概念,这个Stage本身有舞台的意思,寓意是给开发者一个新的展现舞台。Stage模型的设计,主要是为了开发者更加方便地开发出分布式环境下的复杂应用。下表给出了两种模型在设计上的差异:

可以看得出来,新的模型设计的主要目标是把UI与Ability分离,即从架构设计层面,规范开发者编写业务逻辑和UI交互的开发方式。通过数据把UI和业务逻辑解耦,开发者在Ability中产生数据,数据传递给UI框架后,利用ArkTS声明式框架的特点,UI=F(state),通过数据驱动UI变化。这样的设计是为了更好地支持Ability实现跨端迁移和多端协同,即数据都是存储在Ability里,继而通过数据驱动UI展示。此外,FA模型每个Ability使用一个VM实例,而Stage模型整个进程只使用一个VM实例,减少进程内存占用,应用内状态在进程内共享。

分布式音乐播放器,是今年上半年我基于OpenHarmony 3.1,参考OpenHarmony JS分布式音乐播放的Sample代码,使用ArkTS新写的样例,当时的主要目的就是为了学习ArkTS开发页面。此次适配Stage模型后,在润和大禹系列HH-SCDAYU200开发套件上,效果如下图所示:

可以看到,此次更新,不仅使用了Stage模型适配,还使用ArkTS增加了一个音乐播放器首页列表的界面,以及播放时使用属性动画,实现了一个播放音乐时“唱片旋转”的动画效果。这次使用Stage模型适配样例,主要是修改了如下几个地方:

修改点1:代码目录的调整

可以看到,相对于FA的目录结构,首先是在最上层目录里,增加了一个AppScope目录,这个目录下也是resources下的资源文件,比如string.json,图片等内容。这个目录里的资源文件,会在编译时拼接到具体的hap内编译,因此可以把不同hap包里的公用资源提取到这个目录下。

此外是增加了AbilityStage.ts这个文件,它是Hap及加载入口,开发者可以基于它派生完成hap的初始化以及指定多个实例开发。AbilityStage可以配合ApplicationContext监听/管理进程内组件的生命周期,感觉是有点充当了FA模型里的app.ets的作用。

其它的文件也有小的变化,如配置文件,pages位置等都有调整。所以建议还是新建一个stage模型的工程,然后把之前的代码逐步复制过来,然后修改问题。

修改点2:获取设备列表,分布式拉起等API变化

由于两种模型的应用上下文不同,导致一些跟上下文相关的API大都有些变化,在SDK及文档中有明确标明哪些API是stage模型专用的。比如耳熟能详的startAbility分布式拉起应用,在FA模型中是通过以下代码实现:

import featureAbility from '@ohos.ability.featureAbility';featureAbility.startAbility({want: wantValue}).then((data) => {CommonLog.info('startAbilityContinuation finished, ' + JSON.stringify(data))//拉起后,自我关闭featureAbility.terminateSelf((error) => {CommonLog.info('startAbilityContinuation terminateSelf finished, error=' + JSON.stringify(error))})}).catch((error) => {CommonLog.info('startAbilityContinuation error ' + JSON.stringify(error))})

而在stage模型里,由于不再有featureAbility,因此无法import featureAbility,进而无法使用featureAbility.startAbility拉起应用,进而使用getContext获取上下文后,调用startAbility拉起应用。

getContext(this).startAbility(want).then((data) => {CommonLog.info('startAbilityContinuation finished, ' + JSON.stringify(data))//自我关闭getContext(this).terminateSelf((error) => {CommonLog.info('startAbilityContinuation terminateSelf finished, error=' + JSON.stringify(error))})
}).catch((error) => {CommonLog.info('startAbilityContinuation error ' + JSON.stringify(error))
})

除了startAbility外,样例里使用到的获取包含bundleName,设备发现deviceManager的相关API都需要按照上述方法进行修改。

修改点3:数据从组件分离,提取到Ability中

在分布式拉起时,需要传递当前播放的音乐和音乐的播放进度。在两种模型里,这些参数都是被设置在wantValue的parameters里,通过startAbility传出去。

let params = {index: this.playerManager.getCurrentMusicIndex(),seekTo: this.playerManager.getCurrentTimeMs(),isPlaying: this.isPlaying}let wantValue = {bundleName: this.bundleName,abilityName: 'com.madixin.music.MainAbility',deviceId: remoteDevice.deviceId,parameters: params}

但在接收参数时,FA模型里,是在当前组件的代码里,通过featureAbility.getWant来获取参数,如下代码。

featureAbility.getWant((error, want) => {CommonLog.info('restoreFromWant featureAbility.getWant=' + JSON.stringify(want))let status = want.parametersif (status != null && status.index != null) {this.playerManager.playSpecifyMusic(status.seekTo, status.index)this.isPlaying = truethis.playAnimation()}})

而使用Stage模型后,虽然参数传递的方式是一致的,但是无法直接在组件UI中获取参数,而需要先在MainAbility.ts获取参数want。此时如果要传递给组件,有多种方式,这里我是使用的如下方式,即在MainAbility.ts的onCreate和onNewWant里,把want赋值到globalThis里,然后在UI组件里,通过globalThis获取参数。

// MainAbility.ts
onNewWant(want, launchParams) {globalThis.newWant = wanthilog.info(0x0000, 'MyOpenHarmonyPlayer', '%{public}s', 'onNewWant launchParam:' + JSON.stringify(launchParams) ?? '');
}onCreate(want, launchParam) {globalThis.newWant = wanthilog.info(0x0000, 'MyOpenHarmonyPlayer', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');hilog.info(0x0000, 'MyOpenHarmonyPlayer', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
}// index.ets
let newWant = globalThis.newWant
CommonLog.info("aboutToAppear newWant:" + JSON.stringify(newWant))
if (newWant !== null && newWant.parameters.hasOwnProperty("seekTo")) {this.playerManager.playSpecifyMusic(newWant.parameters.seekTo, newWant.parameters.index)
}

另外,了解到还有一种方式传递数据是使用AppStorage来关联,比如在MainAbility.ts里使用AppStorage.SetOrCreate传入数据,在UI组件里,使用@StorageLink标签修饰变量来获取数据。

除以上三点修改外,还有两点值得说明下

首先是因OpenHarmony 3.2后分布式能力限制智能系统应用使用,需要提升apl等级:找到所使用API版本对应toolchains>版本号>lib>UnsgnedReleasedProfileTemplate.json,更改 “apl”: "normal"为 “apl”: “system_core”。

其次是API 9以后区分了public-SDK和Full SDK。DevEco Studio默认下载的是public-SDK,它不包含系统应用所需要的高权限API。当我们import deviceManager from '@ohos.distributedHardware.deviceManager’时,会发现里面只有一个空的接口,没有任何方法。虽然这不影响功能,但代码中必须使用@ts-ignore忽略typescript的告警,而且没有语法提示。此时,需要使用full-SDK替换。

新增首页页面,和播放列表页的动画,不是本文的重点,大家可以参考代码自行学习。

总结

OpenHarmony的FA模型能力已经停止演进,后续将会增强Stage模型。此次将现有的样例代码适配Stage模型,虽然整体代码修改量不大,但因为惯性思维以及API的变化,期间还是踩了不少坑。我已在OpenHarmony知识体系仓中更新了样例代码,欢迎开发者来参考和指正问题,建议新上手OpenHarmony的开发者可以直接学习使用新的Stage模型来开发应用。前面提到在Stage模型里,ExtensionAbility又被扩展为ServiceExtensionAbility、FormExtensionAbility、DataShareExtensionAbility等一系列ExtensionAbility,这个样例目前还没有涉及到,待后续进一步学习,通过ExtensionAbility把音乐播放实现成一个后台服务,从而实现应用在后台时也能继续播放音乐,届时将持续更新这个应用,也欢迎大家一起共建。

为了帮助到大家能够更有效的学习OpenHarmony 开发的内容,下面特别准备了一些相关的参考学习资料:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/332671.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

95.网络游戏逆向分析与漏洞攻防-ui界面的设计-ui的设计与架构

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了 内容…

精品丨快速申请免费https证书

https域名证书对提高网站排名有一定的好处,所以当今很多企业为了给网站一个好的安全防护,就会去申请该证书。如今很多企业虽然重视网站的安全防护,但是也重视成本,所以为了节约成本会考虑申请免费的https证书。 第一个好处 企业不…

用Prometheus全面监控MySQL服务:一篇文章搞定

简介 在现代应用中,MySQL数据库的性能和稳定性对业务至关重要。有效的监控可以帮助预防问题并优化性能。Prometheus作为一款强大的开源监控系统,结合Grafana的可视化能力,可以提供全面的MySQL监控方案。 设置Prometheus 安装Prometheus 使…

机器学习预测-CNN手写字识别

介绍 这段代码是使用PyTorch实现的卷积神经网络(CNN),用于在MNIST数据集上进行图像分类。让我一步步解释: 导入库:代码导入了必要的库,包括PyTorch(torch)、神经网络模块&#xff0…

queue学习

std::queue 类是一种容器适配器,它提供队列的功能——尤其是 FIFO(先进先出)数据结构。此类模板用处为底层容器的包装器——只提供特定的函数集合。queue 在底层容器尾端推入元素,从首端弹出元素。 元素访问 front 访问第一个元素…

Shell环境变量深入:自定义系统环境变量

Shell环境变量深入:自定义系统环境变量 目标 能够自定义系统级环境变量 全局配置文件/etc/profile应用场景 当前用户进入Shell环境初始化的时候会加载全局配置文件/etc/profile里面的环境变量, 供给所有Shell程序使用 以后只要是所有Shell程序或命令使用的变量…

0基础认识C语言

为了给0基础一个舒服的学习路径,就有了这个专栏希望带大家一起进步。 话不多说,开始正题。 一、C语言的一段小历史 C语言的设计要追溯到20世纪60年代末和70年代初,在那个时代美国有这么一号人叫做丹尼斯.里奇,他和同事肯.汤普逊…

【vue】el-select选择器实现宽度自适应

选择器的宽度根据内容长度进行变化 <div class"Space_content"><el-selectv-model"value":placeholder"$t(bot.roommessage)"class"select"size"small"style"margin-right: 10px"change"selectcha…

【MySQL】库的基础操作

&#x1f30e;库的操作 文章目录&#xff1a; 库的操作 创建删除数据库 数据库编码集和校验集 数据库的增删查改       数据库查找       数据库修改 备份和恢复 查看数据库连接情况 总结 前言&#xff1a;   数据库操作是软件开发中不可或缺的一部分&#xff0…

若依框架对于后端返回异常后怎么处理?

1、后端返回自定义异常serviceException 2、触发该异常后返回json数据 因为若依对请求和响应都封装了&#xff0c;所以根据返回值response获取不到Code值但若依提供了一个catch方法用来捕获返回异常的数据 3、处理的方法

如何利用已有数据对模型进行微调

1.langchain整合llm做知识问答 利用LangChain的能力来结合检索和生成&#xff0c;形成一个知识增强的问答系统&#xff08;不涉及对模型的微调&#xff09;&#xff0c;而是利用llm从文档检索到问题解答。 langchain整合llm做知识检索 2.微调llm模型 1、首先是我们的数据集&…

python数据分析——数据可视化(图形绘制)

数据可视化&#xff08;图形绘制基础&#xff09; 前言一、图形绘制基础Matplotlib简介使用过程sin函数示例 二、常用图形绘制折线图的绘制plot示例 散点图的绘制scatter()示例 柱状图的绘制bar示例 箱型图绘制plot.box示例 饼状图的绘制pie示例 三、图形绘制的组合情况多个折线…

HTML静态网页成品作业(HTML+CSS)——宠物狗介绍网页(3个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有3个页面。 二、作品演示 三、代…

HCIP-Datacom-ARST自选题库__BGP判断【20道题】

1.传统的BGP-4只能管理IPV4单播路由信息&#xff0c;MP-BGP为了提供对多种网络层协议的支持&#xff0c;对BGP-4进行了扩展。其中MP-BGP对IPv6单播网络的支持特性称为BGP4&#xff0c;BGP4通过Next Hop属性携带路由下一跳地址信息。 2.BGP4通过Update报文中的Next Hop属性携带…

大模型额外篇章二:基于chalm3或Llama2-7b训练酒店助手模型

文章目录 一、代码部分讲解二、实际部署步骤(CHALM3训练步骤)1)注册AutoDL官网实名认证2)花费额度挑选GPU3)准备实验环境4)开始执行脚本5)从浏览器访问6)可以开始提问7)开始微调模型8)测试训练后的模型三、基于Llama2-7b的训练四、额外补充1)修改参数后2)如果需要访问…

告别红色波浪线:tsconfig.json 配置详解

使用PC端的朋友&#xff0c;请将页面缩小到最小比例&#xff0c;阅读最佳&#xff01; tsconfig.json 文件用于配置 TypeScript 项目的编译选项。如果配不对&#xff0c;就会在项目中显示一波又一波的红色波浪线&#xff0c;警告你这些地方的类型声明存在问题。 一般我们遇到这…

C语言对一阶指针 二阶指针的本质理解

代码&#xff1a; #include <stdio.h>char a 2; char* p &a; char** d &p;int main(){printf("a -> %d, &a -> %p\n", a, &a);printf("*p -> %d, p -> %p, &p -> %p\n", *p, p, &p);printf(&qu…

Java Swing + MySQL图书借阅管理系统

系列文章目录 Java Swing MySQL 图书管理系统 Java Swing MySQL 图书借阅管理系统 文章目录 系列文章目录前言一、项目展示二、部分代码1.Book2.BookDao3.DBUtil4.BookAddInternalFrame5.Login 三、配置 前言 项目是使用Java swing开发&#xff0c;界面设计比较简洁、适合作…

ic基础|时钟篇05:芯片中buffer到底是干嘛的?一文带你了解buffer的作用

大家好&#xff0c;我是数字小熊饼干&#xff0c;一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结&#xff0c;并通过汇总成文章的形式进行输出&#xff0c;相信无论你是在职的还是…

计算机毕业设计 | SpringBoot招投标 任务发布网站(附源码)

1&#xff0c;绪论 在市场范围内&#xff0c;任务发布网站很受欢迎&#xff0c;有很多开发者以及其他领域的牛人&#xff0c;更倾向于选择工作时间、工作场景更自由的零工市场寻求零散单子来补贴家用。 如今市场上&#xff0c;任务发布网站鱼龙混杂&#xff0c;用户需要找一个…