点击蓝字 ╳ 关注我们
开源项目 openharmony是每个人的 openharmony 马迪欣
openharmony知识体系工作组
以下内容来自嘉宾分享,不代表开放原子开源基金会观点 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.parameters if (status != null && status.index != null) { this.playermanager.playspecifymusic(status.seekto, status.index) this.isplaying = true this.playanimation() } }) 而使用stage模型后,虽然参数传递的方式是一致的,但是无法直接在组件ui中获取参数,而需要先在mainability.ts获取参数want。此时如果要传递给组件,有多种方式,这里我是使用的如下方式,即在mainability.ts的oncreate和onnewwant里,把want赋值到globalthis里,然后在ui组件里,通过globalthis获取参数。 // mainability.ts onnewwant(want, launchparams) { globalthis.newwant = want hilog.info(0x0000, 'myopenharmonyplayer', '%{public}s', 'onnewwant launchparam:' + json.stringify(launchparams) ''); } oncreate(want, launchparam) { globalthis.newwant = want hilog.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替换。 相关文档请参考 https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/full-sdk-switch-guide.md
新增首页页面,和播放列表页的动画,不是本文的重点,大家可以参考代码自行学习。 总结
openharmony的fa模型能力已经停止演进,后续将会增强stage模型。此次将现有的样例代码适配stage模型,虽然整体代码修改量不大,但因为惯性思维以及api的变化,期间还是踩了不少坑。我已在openharmony知识体系仓中更新了样例代码,欢迎开发者来参考和指正问题,建议新上手openharmony的开发者可以直接学习使用新的stage模型来开发应用。 前面提到在stage模型里,extensionability又被扩展为serviceextensionability、formextensionability、datashareextensionability等一系列extensionability,这个样例目前还没有涉及到,待后续进一步学习,通过extensionability把音乐播放实现成一个后台服务,从而实现应用在后台时也能继续播放音乐,届时将持续更新这个应用,也欢迎大家一起共建。 分布式音乐播放器样例地址 https://growing.openharmony.cn/mainplay/detail?sampleid=3742
原文标题:我把分布式音乐播放器适配了stage模型
文章出处:【微信公众号:openatom openharmony】欢迎添加关注!文章转载请注明出处。
OPTIGA™ Trust X为物联网安全保驾护航
电子技术基础:电容
PET塑钢打包带出现打包不牢固情况的原因是什么
一种简单而有效的多通道微流控电化学传感器
采用TMS320VC5402作主控制器芯片实现USB语音传输接口装置设计
我把分布式音乐播放器适配了Stage模型
致真精密仪器荣获首届“金燧奖”中国光电仪器品牌榜铜奖
VR技术加持学校安全教育,以确保校园平安
工业以太网交换机的作用
vivo多款机型通过国家3C认证入网
锤子科技转让股份给阿里巴巴 罗永浩要傍马云大腿?
pci卡设计心得
英飞凌2011年财报 营收和利润率均创历史新高
机器人真的在抢人类的饭碗,还是在弥补劳动力不足?
虚拟资产期货合约平台开发,数字资产合约系统,源中瑞Dave
百卓网络的5G安全业务市场发展情况分析
关于显示器的常用接口你了解吗
顺风车的特殊性,对顺风车的管理应该多一些宽容
石墨烯原子缺陷是如何形成的?
世界上拥有大量比特币的十大持有者介绍