评论

收藏

[PHP] HarmonyOS3.0尝鲜之关键Js Api--ServiceAbility开发

开发技术 开发技术 发布于:2022-08-19 14:59 | 阅读数:415 | 评论:0

HarmonyOS3.0发布之后,大家可以从api8上可以看到一个关键动作,就是完全抛弃了java,并且不提供对api8以下版本的兼容,完全颠覆性变化,显然不可能再去兼容低版本了。那么做过api7之前开发的朋友都会知道,在之前的js或者ets开发中,有几个关键地方是离不开java的,比如我前面一篇博客中写道的动态权限申请,本篇将来介绍另一个关键技术ServiceAbility,之前的ServiceAbility是完全基于Java开发,可以说和Android里面的开发模式一样。
下面就来上手尝试下ServiceAbility纯粹js或者ets开发吧,这里稍微吐槽下官方文档的不足吧,我已经反馈官方整改文档了。文档上的一些小错误和不足导致我打通Service的所有核心技能足足耗费了十多个小时,其中最难的莫过于Service主动给FA推送数据了,做过Android的可能都知道在Android里面这个是基于java的回调机制来实现,而这里官方文档是没有说这个核心技能是如何实现的,js的回调机制和java的回调机制还是有非常大区别的,我开始专在回调里面出不来导致耗费了很久时间,最后又尝试了N中方案终于最后找到了最优解搞定了这个核心功能。
本篇文章先主要来个Js版本的ServiceAbility开发入门吧。

场景介绍
基于Service模板的Ability(以下简称“Service”)主要用于后台运行任务(如执行音乐播放、文件下载等),但不提供用户交互界面。Service可由其他应用或Ability启动,即使用户切换到其他应用,Service仍将在后台继续运行。

接口说明
表1 Service中相关生命周期功能介绍

DSC0000.png

开发步骤
本篇先只实现最基本的创建、启动和停止Service。

创建工程
首先使用最新版的DevEco Studio(992版本)开发工具创建一个工程,选择最新的api8,如下图

DSC0001.png

DSC0002.png

创建工程时,需要关注的就是上图中所描述的bundleName和package,因为后面核心api中要使用到这两个参数,对于这两个参数含义不清楚的可以查阅我另外一篇博客《App与Hap、Entry与feature,bundleName与packge,务必弄明白》

创建Service
工程创建完成之后,鼠标选择js目录,然后点击鼠标右键,如下图依次选择来创建Service

DSC0003.png

DSC0004.png

Service也是一种Ability,Ability为Service提供了以下生命周期方法,开发者可以重写这些方法,来添加其他Ability请求与Service Ability交互时的处理方法。

创建Service的代码示例如下:
export default {
  onStart(want) {
    console.info('ServiceAbility onStart');
  },
  onStop() {
    console.info('ServiceAbility onStop');
  },
  onConnect(want) {
    console.info('ServiceAbility onConnect');
    return {};
  },
  onReconnect(want) {
    console.info('ServiceAbility onReconnect');
  },
  onDisconnect() {
    console.info('ServiceAbility onDisconnect');
  },
  onCommand(want, restart, startId) {
    console.info('ServiceAbility onCommand');
  }
};
本篇将只讲解启动和停止服务,等会写完启动和停止服务的触发代码之后,我们再来看看会有哪些生命周期函数会被回调。

由于Service也是Ability,创建完成Service之后,它也会自动的在应用配置文件config.json中生成相关核心配置信息,其中有个核心配置就是type为“service”,具体如下所示:
{
   "module": {
     "abilities": [     
       {  
         "name": ".ServiceAbility",
         "type": "service",
         "visible": true
         ...
       }
     ]
     ...
   }
   ...
 }
启动Service
做个极其简单的页面,只放置两个文本按钮,分别用来触发“启动Service”和“停止Service”,如下图

DSC0005.png

Ability为开发者提供了startAbility()方法来启动另外一个Ability。因为Service也是Ability的一种,开发者同样可以通过将Want传递给该方法来启动Service。

开发者可以通过构造包含bundleName与abilityName的Want对象来设置目标Service信息。参数的含义如下:
- bundleName:表示应用唯一标识符名称,即config.json中的bundleName。
- abilityName:表示待启动的Ability名称,这里使用完整Ability名称,即package+‘.’+Ability名称。
启动本地设备Service的代码示例如下:
首先要导入系统库
import featureAbility from ‘@ohos.ability.featureAbility’;

然后业务逻辑代码如下:
//启动service按钮绑定的点击事件
  onClickStartService(){
    let promise = featureAbility.startAbility(
      {
        want:
        {
          bundleName: "com.xdw.jsdemo",
          abilityName: "com.example.entry.ServiceAbility",
        },
      }
    );
  }
执行上述代码后,Ability将通过startAbility() 方法来启动Service。

- 如果Service尚未运行,则系统会先调用onStart()来初始化Service,再回调Service的onCommand()方法来启动Service。
- 如果Service正在运行,则系统会直接回调Service的onCommand()方法来启动Service。
不支持预览器进行测试,下面启动模拟器或者真机(必须api》=8)进行测试,多次点击“启动Service”按钮观察日志输出,日志输出如下图

DSC0006.png
停止Service
Service一旦创建就会一直保持在后台运行,除非必须回收内存资源,否则系统不会停止或销毁Service。开发者可以在Service中通过featureAbility.terminateSelf()停止本Service。
这里需要注意的是官方sdk目前并没有提供在其他Ability中主动停止Service的api,因此现在想简简单单的在UI中点击“停止service”按钮直接调用一个api停止service是做不到的,但并不是代表就不能通过点击按钮来停止服务,关于这个的实现下篇再讲。这里只讲通过在当前Service中通过featureAbility.terminateSelf()停止本Service。由于不是主动通过UI操作的,什么时候去停止服务需要个触发时机,最简单的就是在Service中添加一个定时器来做demo演示了。代码如下:
onStart(want) {
    console.info('ServiceAbility onStart');
    //5秒之后停止Service
    setTimeout(()=>{
  console.info('delay 5秒');
      featureAbility.terminateSelf();
    },5000)
  },
但是这里尝试,发现尝试了好多次之后发现目前在Service中不支持setTimout定时器的运行,还不知道是有意这么设计的还是缺陷bug,已经反馈给华为官方进行跟进。那么只能换一种最low的方式来演示了,代码如下:
onCommand(want, restart, startId) {
    console.info('ServiceAbility onCommand');
    featureAbility.terminateSelf();
  }
最后运行日志截图如下:
DSC0007.png
小结
在官方文档基础上,把操作步骤和一些关键解释描述的更加详细,更加方便小白入手,防止入坑。
本篇只是入门级开胃小菜,我最终用这个Service的目的是为了在我智能家居的项目中,手机端通过该AbilityService实时接收服务端推送过来的数据,然后Service中接收到服务端推送过来的数据之后可以主动更新UI对应的Ability中的数据,即需要打通Service主动向Activity中传递数据这个关键技术点。详细打通流程会在下篇文章中讲解,这个是目前官网上面没有的内容。


关注下面的标签,发现更多相似文章