【FFH】ArkUI Service Ability开发实战详解 原创 精华
【FFH】ArkUI Service Ability开发实战详解(API 9)
前言
本篇的demo使用的是ArkUI的js开发,eTs的Service Ability开发与js流程基本一致,把 js 换成 ts 语言即可。
为了充分体验Service Ability的特性,这次的Demo由浅入深演示了三个功能的实现:
- 一是调用service Ability来拼接字符串,即做一些数据处理业务。——同步实现
- 二是结合了系统 公共事件与通知能力的Notification模块(js api) 来模拟Service在后台运行的场景,发送完就拉起特定页面。——异步实现
- 三是使用下载接口request来尝试后台下载文件的场景,在实际场景中,可以实现应用在后台下载完一些文件或安装包后自动拉起特定的页面(不知道是不是接口的原因,监听不到下载完毕的事件回调,只能在在通知栏找到下载完毕的通知)。——异步实现
相关知识
1、Service
Ability是鸿蒙应用程序的重要组成部分,在鸿蒙开发FA(feature Ability)模型中,Ability分为PageAbility(FA)、ServiceAbility(PA)、DataAbility(PA)、FormAbility四种类型,PageAbility是我们熟知的UI交互页面,DataAbility用于后台数据管理服务,FormAbility是服务卡片。ServiceAbility是PA类型一种,没有UI,它提供其他Ability调用自定义的服务,在后台运行。
在本机上,Service属于单实例、不会自动中断(除非系统回收资源)的系统后台服务,本机的应用可通过Service Ability等ability来使用它的能力,我们可以利用它的功能来实现像音乐播放、文件下载等需要在页面隐藏或者销毁还能继续运行的服务,是非常重要的一个能力,只不过在os的api9以前,ArkUI(js)想要创建Service Ability后台服务只能在通过js侧调用java侧来实现,但自从open Harmony api9(对应os api9)起,官方取消了js+java的混合开发模式,改为纯js开发,并更新了一批接口,于是就来尝试一下新接口的能力,打通一遍JS ServiceAbility的开发流程。
Service Ability官方文档
2、Service Ability生命周期
一共六个生命周期:
onStart | onStop | onConnect | onReconnect | onDisconnect | onCommand |
---|
官方文档写到:根据调用方法的不同,其生命周期有两种路径。验证了一下后,大致地整理了一个流程图:
多个客户端可以绑定到相同Service,而且当所有绑定全部取消后,系统即会销毁该Service。官方文档中说可以人为通过调用stopAbility()来停止Service,但目前只在java侧可以找到这个接口,js侧还没有发布。
3、RPC进程间通信
鸿蒙系统在不同进程间采取的是rpc通信的方式。ServiceAbility使用时,Service后台和PageAbility是两个隔离的进程,需要借助rpc接口来实现通信,两者通过IRemoteObject实例来传递数据,利用MessageParcel提供读写方法来包装数据,最后调用IRemoteObject的sendRequest方法实现信息的发送。
import rpc from ‘@ohos.rpc’;
本篇主要用到三个实例,后面会融入demo详细说说:
MessageParcel | 用途 |
---|---|
该类提供读写基础类型及数组、IPC对象、接口描述符和自定义序列化对象的方法。 | 包装数据对象 |
MessageOptions | 用途 |
---|---|
公共消息选项(int标志,int等待时间),使用标志中指定的标志构造指定的MessageOption对象。 | 配置:是否异步(默认同步1)、等待时间 |
IRemoteObject | 用途 |
---|---|
该接口可用于查询或获取接口描述符、添加或删除死亡通知、转储对象状态到特定文件、发送消息。 | 信息传输工具 |
代码实现
工程结构目录
图中的ServiceAbility包便是编写ServiceAbility服务代码的地方
一、拼接字符串实现流程
在entry右键->new->ability栏选择Service Ability
自己起一个包名,这个包名是后面连接Service Ability会用到的
创建完后,在ServiceAbility包下会出现service.js的文件,js有官方给的模板代码,包含ServiceAbility的所有生命周期:onStart、onStop、onConnect、onReconnect、onDisconnect、onCommand。
因为Service Ability也是属于ability的范围,因此它可以像Page Ability一样通过featureAbility的startAbility、connectAbility方法拉起进程。
1、startAbility()方法
包名bundleName和类名abilityName都可以在config.json中找到。其中bundleName是直接给出的,abilityName是"package"+“.”+包名。
2、connectAbility()方法
onnectAbility比startAbility多出一个参数用于接收连接的回调
- 连接成功时onConnect
- 连接失败时onFailed
- 连接中断时onDisconnect
当我们调用connectAbility时触发onConnect就说明连接成功,可在onConnectCallback的回调参数中找到remoteObject实例。
Service Ability侧响应
Page Ability主动连接(connectAbility)时,触发onConnect,Service Ability就返回一个IPremoteObject实例给Page Ability使用;
封装ServiceModel.js工具类
封装上面提到的接口
先来个流程测试:前端发送一段字符串到Service Ability,拼接处理后返回前端。
1. 发送方启动Service Ability
startAbility或connectAbility都可以拉起ability,其中的区别参考上文的生命周期流程图
2. 由接收方建立通信通道(remoteObject)并把通道返回给发送方
remoteObject就是上面提到的用于传递信息的通道,它提供的接口很多,其中最主要的两个方法是sendRequest和onRemoteRequest:
- sendRequest为发送方调用,发送数据
- onRemoteRequest为接收方调用,监听发送的数据
在service.js中增加一个类,super继承父类rpc.RemoteObject,并重写onRemoteRequest方法:
当Page Ability发起连接请求时(connectAbility),Service Ability会收到请求并触发生命周期onConnect,对应接收方的onConnectCallback回调,我们在回调参数结果中获取到remoteObject赋值给全局变量mRemote。
3. 发送方获取通信通道
获取remoteObject实例:
4. 发送数据
sendRequest(code:number, data:rpc.MessageParcel, reply:rpc.MessageParcel, option:rpc.MessageOption)
- data和reply都是MessageParcel对象,是对数据的包装,对外提供读写方法。data和reply可看作两条单向读写通道,data只对发送方可写,reply只对接收方可写。
- MessageOption是对此次通信的配置,可配置的选项:
setFlags | setWaitTime |
---|---|
同步1(默认)、异步0 | 最长等待响应时间(reply) |
5. Service Ability接收数据并处理
通过code识别发送方的意图
6. 前端获取处理完的数据
在reply拿到处理完的数据(这一步用于需要同步的数据处理)
7. 效果展示
控制台打印:
二、后台发送通知实现流程
后台发送通知 与上文的 拼接字符串 的区别在于:
- 体现后台执行的特点。
- 使用异步执行,数据不需要同步,执行完自动后拉起某个页面
效果演示
Page Ability侧
因为后台发送,option.setFlags设置为异步,并且先销毁当前页面 featureAbility.terminateSelf()
Service Ability侧
Service Ability拉起、连接与上文 拼接字符串 的流程一致
只需增加不同的code来识别
简单介绍一下公共事件与通知能力的Notification模块
config.json配置权限:
“reqPermissions”: [{
“name”: “SystemCapability.Notification.Notification”
}]
简单的发送普通文本通知示例:
关于为什么用递归方式发送通知而不用定时器,因为Service Ability使用不了这种用在前端的函数,不仅包括setTimeout、setInterval,还有像new Image()、new offscreen()之类的也用不了,可能是官方有意为之。
三、后台下载实现流程
效果演示
Page Ability侧
同样地设置异步执行并销毁当前页面
Service Ability侧
原本想下载大一点的文件但是效果不太给力,所以就简单地调用一下request的接口下载一张图片。
request接口详细文档
配置网络权限:
“reqPermissions”: [{
“name”: “ohos.permission.INTERNET”
}]
完整代码
UI界面:
结语
这次Js Service Ability的开发条过程也是啃着文档,但最后总算是成功打通了一遍流程,了解到它的一些原理。希望这篇文章能给准备尝试Js的Service Ability的人提供一些帮助。
Service Ability是很实用的一种应用后台ability,它能牵涉到鸿蒙系统的各种各样的子系统功能,学习Service Ability同时也是深入学习鸿蒙系统的原理、架构、接口能力等技术的途径。
整理全面,讲解详细,必须支持
代码躺在附件和自己电脑,都是很浪费的。
建议研究下提交到OpenHarmony的知识体系代码仓里。
怎么参加代码提交,可以去翻一下“战码先锋”相关回播,一大堆课程在做讲解。
感谢支持~
不错不错,比较详细